2012-11-29 87 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而不處理它,因爲它不能清理任何非託管資源。