For*_*ore 7 .net rest wcf exception-handling exception
我们有一个使用WCF构建的REST API.
我们使用WebFaultException处理所有异常后端,如下所示:
throw new WebFaultException<string>(e.Message, HttpStatusCode.NotAcceptable);
Run Code Online (Sandbox Code Playgroud)
除了我们使用流做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);
Run Code Online (Sandbox Code Playgroud)
在using语句中处理这个流时,每当我们遇到异常时,我们都会得到:
来自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& fault)</p>
Run Code Online (Sandbox Code Playgroud)
看起来它与流和StreamReader有关.
然后我尝试删除任何将处理StreamReader的东西,这个acctualy工作.现在处理此代码的代码如下所示:

这解决了发送正确异常消息的问题,但是这会对我们的应用程序造成多大影响,而不是关闭或处理我们的StreamReader?你还有其他解决方法吗?
发生这种情况是因为StreamReader接管了流的"所有权".换句话说,它使自己负责关闭源流.一旦您的程序调用Dispose或Close(在您的情况下保留using语句范围),它也将处理源流.在你的情况下调用sr.Dispose().所以文件流已经死了.
如果您不想这样,您可以创建一个继承自StreamReader并覆盖Close方法的新类; 在Close方法中,调用Dispose(false),它不会关闭流.
你也可以使用NonClosingStreamWrapperJon Skeet的MiscUtil库中的类,它正是为了这个目的.
但是最好不要在没有处理它的情况下离开StreamReader,因为它无法清除任何非托管资源.
| 归档时间: |
|
| 查看次数: |
1382 次 |
| 最近记录: |