使用Stream并关闭流时,WebFaultException错误 [英] Wrong WebFaultException when using a Stream and closing the stream

查看:316
本文介绍了使用Stream并关闭流时,WebFaultException错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个使用WCF构建的REST API。



我们使用WebFaultException处理所有异常后端,如下所示:

 抛出新的WebFaultException< string>(e.Message,HttpStatusCode.NotAcceptable); 

这个工作很正常,除了在一个我们做一个Post,一个流的情况下。



一个例子:

  [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);

在使用语句处理此流时,每当遇到异常时,我们会继续: / p>

来自Fiddler:

  HTTP / 1.1 400错误请求
< p>服务器在处理请求时遇到错误。异常消息是消息对象已被处理。有关详细信息,异常堆栈跟踪是:< / p>
< p>在System.ServiceModel.Channels.ByteStreamMessage.InternalByteStreamMessage.get_Properties()
在System.ServiceModel.OperationContext.get_IncomingMessageProperties()
在System.ServiceModel.Dispatcher.WebErrorHandler.ProvideFault(异常错误,MessageVersion版本,消息和amp ; amp; fault)< / p>

看起来它与流和StreamReader的处理有关。



然后,我尝试删除将处理StreamReader的任何东西,这个acctualy可以正常工作。代码处理现在看起来像这样:





这解决了发送正确的异常消息的问题,但这会影响我们的应用程序有多糟,而不是关闭或处理我们的StreamReader?
你有没有其他的解决方法?

解决方案

这是因为StreamReader接管流的所有权。换句话说,它负责关闭源流。一旦你的程序调用Dispose或Close(在你的情况下留下using语句范围),那么它也将处理源流。在你的情况下调用sr.Dispose()。所以文件流已经死了。



如果你不想这样做,你可以创建一个继承自StreamReader并覆盖Close方法的新类;在你的关闭方法中,调用不关闭流的Dispose(false)。



你也可以使用 NonClosingStreamWrapper 来自Jon Skeet的 MiscUtil 库的课程,它完全符合这一目的。



但是最好不要离开StreamReader而不处理它,因为它不能清除任何非托管资源。


We have a REST API, built with WCF.

We handle all the exceptions backend with WebFaultException like this:

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

This works just fine except in one scenario where we do a 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 handling this stream in a using statement, whenever we then run into an exception we keep getting:

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>

Looks like it has something to do with the stream and StreamReader being disposed.

I have then tried to remove anything that will dispose the StreamReader, and this acctualy works. The code handling this now looks like this:

This solves the problem with sending correct exception messages, but how bad will this affect our application, not closing or disposing our StreamReader? Do you see any other ways of solving this ?

解决方案

This happens because the StreamReader takes over 'ownership' of the stream. In other words, it makes itself responsible for closing the source stream. As soon as your program calls Dispose or Close (leaving the using statement scope in your case) then it will dispose the source stream as well. Calling sr.Dispose() in your case. So the file stream is dead after.

If you don't want this you could create a new class which inherits from StreamReader and override the Close method; inside your Close method, call Dispose(false) which does not close the stream.

You could also use the NonClosingStreamWrapper class from Jon Skeet's MiscUtil library, it serves exactly that purpose.

But it would be better to not leave the StreamReader without disposing it because it can't clean any unmanaged resources.

这篇关于使用Stream并关闭流时,WebFaultException错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆