Incorrect WebFaultException when using a thread and closing a thread

We have a REST API built using WCF.

We handle all exceptions using WebFaultException as follows:

throw new WebFaultException<string>(e.Message, HttpStatusCode.NotAcceptable); 

This works fine, except for one scenario where we do Post with a stream.

An example of this:

 [WebInvoke(Method = "POST", UriTemplate = "saveUser?sessionId={sessionId}&userId={userId}", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] [OperationContract] string SaveUser(string sessionId, int userId, Stream stream); 

When processing this thread in the using statement, whenever we throw an exception, we continue to receive:

From Fiddler:

 HTTP/1.1 400 Bad Request <p>The server encountered an error processing the request. The exception message is 'The message object has been disposed.'. See server logs for more details. The exception stack trace is: </p> <p> at System.ServiceModel.Channels.ByteStreamMessage.InternalByteStreamMessage.get_Properties() at System.ServiceModel.OperationContext.get_IncomingMessageProperties() at System.ServiceModel.Dispatcher.WebErrorHandler.ProvideFault(Exception error, MessageVersion version, Message&amp; fault)</p> 

It looks like this has to do with Stream and StreamReader.

Then I tried to remove everything that StreamReader will destroy, and this acctualy works. Code processing now looks like this:

enter image description here

This solves the problem of sending the correct exception messages, but how badly will it affect our application and not the closing or deleting of our StreamReader? Do you see any other ways to solve this?

+7
source share
1 answer

This is because StreamReader takes ownership of the stream. In other words, it is responsible for closing the source stream. As soon as your program calls Dispose or Close (leaving the scope of the statement in your case), it will also remove the source stream. Call sr.Dispose () in your case. So the file stream is dead after.

If you do not want this, you can create a new class that inherits from StreamReader and overrides the Close method; inside the Close method, call Dispose (false), which does not close the stream.

You can also use the NonClosingStreamWrapper class from the Jon Skeet MiscUtil library , it serves exactly this purpose.

But it would be better not to leave StreamReader without deleting it, because it cannot clear unmanaged resources.

+7
source

All Articles