2012-11-29 49 views
7

我们有一个REST API,使用WCF构建。使用流并关闭流时发生错误的WebFaultException

我们处理与WebFaultException后端像这样的所有异常:

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

在这里我们做一个帖子这个工程除了在一个场景就好了,甲流。

这样的一个例子:

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

当using语句处理这个流,当我们再碰上我们不断收到一个例外:

从小提琴手:

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> 

看起来它与流和StreamRead有关呃被处置。

然后,我试图删除任何将放置StreamReader,这acctualy的作品。现在处理这个代码看起来是这样的:

enter image description here

这解决了与发送正确的异常信息的问题,而是如何不好这会不会影响我们的应用程序,不关闭或处置我们的StreamReader? 你有没有看到解决这个问题的其他方法?

回答

7

发生这种情况是因为StreamReader接管了流的“所有权”。换句话说,它负责关闭源码流。只要你的程序调用Dispose或Close(在你的情况下留下使用语句范围),它也会处理源流。在你的情况下调用sr.Dispose()。所以文件流已经死了。

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

您也可以使用Jon Skeet的MiscUtil库中的NonClosingStreamWrapper类,它正是用于此目的。

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