【问题标题】:How can I intercept an exception occurred during serialization in WCF?如何拦截 WCF 序列化期间发生的异常?
【发布时间】:2012-11-26 16:06:22
【问题描述】:

我有一个包含所有数据协定/数据成员属性的合法数据对象。 由于某种原因,WCF 服务在操作完成后崩溃,结果作为返回值传递。 我相信这与 WCF 无法正确序列化该结果有关。测试客户端没有说任何具体的内容:

The underlying connection was closed: The connection was closed unexpectedly.

Server stack trace: 
   at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at IFacade.PickSecurities(String pattern, Int32 atMost)
   at FacadeClient.PickSecurities(String pattern, Int32 atMost)

Inner Exception:
The underlying connection was closed: The connection was closed unexpectedly.
   at System.Net.HttpWebRequest.GetResponse()
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

我可以控制使用自定义服务主机工厂创建服务实例。

我知道我可以设置跟踪侦听器并检查日志,但是这样做很麻烦。所以我宁愿在它发生的时候在服务器上明确地处理它。

那么我该如何以编程方式拦截该异常并返回适当的故障信息?

更新

对于那些主张使用 system.diagnostics 跟踪日志进行故障排除的人。您能通过查看以下日志条目告诉我有什么问题吗?

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131075</EventID>
<Type>3</Type>
<SubType Name="Error">0</SubType>
<Level>2</Level>
<TimeCreated SystemTime="2012-11-26T16:20:41.8343508Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{2d6e8a90-a784-4add-a9b6-9fd9c37b7b0f}" />
<Execution ProcessName="WebDev.WebServer40" ProcessID="5104" ThreadID="10" />
<Channel />
<Computer>WASWK060</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>4eaf36d4-1-129984204415953508</AppDomain>
<Exception>
<ExceptionType>System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>There is a problem with the XML that was received from the network. See inner exception for more details.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
at System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state)
at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.ServiceModel.ProtocolException: There is a problem with the XML that was received from the network. See inner exception for more details. ---&gt; System.Xml.XmlException: The body of the message cannot be read because it is empty.
   --- End of inner exception stack trace ---</ExceptionString>
<InnerException>
<ExceptionType>System.Xml.XmlException, System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The body of the message cannot be read because it is empty.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
at System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state)
at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.Xml.XmlException: The body of the message cannot be read because it is empty.</ExceptionString>
</InnerException>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>

另一个

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131075</EventID>
<Type>3</Type>
<SubType Name="Error">0</SubType>
<Level>2</Level>
<TimeCreated SystemTime="2012-11-26T16:20:41.8383508Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{2d6e8a90-a784-4add-a9b6-9fd9c37b7b0f}" />
<Execution ProcessName="WebDev.WebServer40" ProcessID="5104" ThreadID="10" />
<Channel />
<Computer>WASWK060</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>4eaf36d4-1-129984204415953508</AppDomain>
<Exception>
<ExceptionType>System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>Content Type application/soap+xml; charset=utf-8 was sent to a service expecting text/xml; charset=utf-8.  The client and service bindings may be mismatched.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpInput.ThrowHttpProtocolException(String message, HttpStatusCode statusCode, String statusDescription)
at System.ServiceModel.Channels.HttpInput.ValidateContentType()
at System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(Exception&amp; requestException)
at System.ServiceModel.Channels.HttpRequestContext.CreateMessage()
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
at System.ServiceModel.AspNetPartialTrustHelpers.PartialTrustInvoke(ContextCallback callback, Object state)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequestWithFlow(Object state)
at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.ServiceModel.ProtocolException: Content Type application/soap+xml; charset=utf-8 was sent to a service expecting text/xml; charset=utf-8.  The client and service bindings may be mismatched.</ExceptionString>
<DataItems>
<Data>
<Key>System.ServiceModel.Channels.HttpInput.HttpStatusCode</Key>
<Value>UnsupportedMediaType</Value>
</Data>
<Data>
<Key>System.ServiceModel.Channels.HttpInput.HttpStatusDescription</Key>
<Value>Cannot process the message because the content type 'application/soap+xml; charset=utf-8' was not the expected type 'text/xml; charset=utf-8'.</Value>
</Data>
</DataItems>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>

我做不到。现在,当我知道问题出在哪里时,我可以告诉您,此日志记录并没有为您提供任何可以引导您解决问题的信息。

【问题讨论】:

  • 正如我所说,我对诊断解决方案不感兴趣 :)
  • “诊断解决方案”将帮助您找出问题所在,以便您解决问题。
  • 哈哈 为什么没人听?我不需要你的诊断,问题是关于如何以编程方式处理序列化异常。
  • 已在下面添加了答案,但我也同意 @ArsenMkrt 的观点,即您应该启用诊断。

标签: .net wcf serialization error-handling


【解决方案1】:

看看这篇文章:- http://www.creativecodedesign.com/node/58

<behaviors>
  <serviceBehaviors>
    <behavior name="SomeServiceServiceBehavior">      
      <serviceDebug includeExceptionDetailInFaults="true"/>
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
  </serviceBehaviors>
</behaviors>

includeExceptionDetailInFaults 是我认为你需要的。

更新 对于您遇到的错误

内容类型 application/soap+xml; charset=utf-8 被发送到服务 期待文本/xml;字符集=utf-8。客户端和服务绑定可以 不匹配。

您的服务器和客户端绑定似乎不匹配。并不是您的 XML 格式不正确,而是它没有以服务器根据服务器端绑定配置所期望的格式发送。您需要确保服务器和客户端的绑定类型相同(例如 basicHttpBinding 或 wsHttpBinding)。

Client and service binding mismatch

【讨论】:

  • 不幸的是,该属性不处理序列化异常。
  • 好吧,你说“我相信这与 WCF 无法正确序列化该结果有关。”但你不确定。您需要启用诊断以了解发生了什么。无论如何,在开发过程中将异常详细信息包含在故障中对您很有用。
  • 我现在确定这是一个序列化问题。在问题正文中找到更新以获取详细信息(实际上日志记录没有任何详细信息支持我不使用它的观点,因为它没用)。
  • 日志告诉您确切地出了什么问题。客户端和服务器配置之间的绑定期望不匹配。这根本不是序列化问题。
  • 我多次重新生成客户端代理(更新了服务参考),试图摆脱这个归咎于绑定的误导性错误消息。相信我最新最好的代理代码、更新的配置和匹配的绑定(我通过查看配置文件手动检查了服务器和客户端)它没有帮助。所以你所说的“完全错误”实际上并不那么准确。正如我所说,问题在于缺少 KnownType 属性,该属性不会阻止生成代理,但在调用服务时序列化结果失败。
【解决方案2】:

在 IIS 中,将您的 Application Pool Identity 设置为 Local System

它对我有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多