0

I have a legit data object with all data contract / data member attributes. For some reason the WCF service crashes after the operation has completed and the result is passed as a return value. I believe it has something to do with WCF not being able to serialize that result properly. The test client doesn't say anything specific:

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)

I am in control of creating the instance of the service using a customized service host factory.

I know I can set up trace listeners and check the logs, but it's a lot of hassle to do. So I would rather handle it explicitly on the server at the time it happens.

So I how can I intercept that exception programmatically and return an appropriate fault meassage?

UPDATE

For those who advocates using the system.diagnostics trace log for troubleshooting. Can you tell me what is the problem by the looking at the following log entries?

<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>

Another one

<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>

I wasn't able to do so. Now when I know what the problem was I can tell that this log record doesn't give you anything that can lead you to the resolution of the problem.

Trident D'Gao
  • 18,973
  • 19
  • 95
  • 159
  • 2
    turn on and take a look into wcf diagnostics(http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2005/12/15/5662.aspx) – Arsen Mkrtchyan Nov 26 '12 at 16:09
  • as I said I am not interested in diagnostics solution :) – Trident D'Gao Nov 26 '12 at 16:22
  • 2
    The "diagnostics solution" will help you figure out what the problem is, so that you can solve it. – John Saunders Nov 26 '12 at 16:25
  • Haha Why isn't anybody listening? I don't need your diagnostics, question is about how one handle the serialization exception programmatically. – Trident D'Gao Nov 26 '12 at 16:33
  • Have added an answer below, but I also agree with @ArsenMkrt that you should enable diagnostics. – Nick Ryan Nov 26 '12 at 17:23
  • I already enabled that tracing information, unfortunately the exception from the log didn't provide any clue on what the reason for that problem was.Although I already figured that out, I still think is very annoying that there is no proven way to get these problems diagnosed fast and easily in WCF. Every time it is a fight with a blackbox. Ugh! – Trident D'Gao Nov 26 '12 at 17:29
  • Please don't try to be so offensive. Tracing is the way to go; WCF doesn't invoke your service method if there's any problem with the data it receives. In your case this question may be relevant, based on the error: http://stackoverflow.com/questions/10403806/wcf-soap-1-2-service-expecting-soap-1-1-content-type – CodeCaster Nov 26 '12 at 18:17
  • I am not trying to offence anyone. I am saying that in this particular case the tracing information is useless. As well as in pretty much any other case when it comes to serialization. This is why the question is posed like that: how can I catch the exception that happens during serialization. – Trident D'Gao Nov 26 '12 at 18:20
  • Speaking of my particular problem, here is the link to the answer that I ended up with trying to solve it: http://stackoverflow.com/a/13569437/139667 – Trident D'Gao Nov 26 '12 at 18:22

2 Answers2

1

Have a look at this article:- http://www.creativecodedesign.com/node/58

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

includeExceptionDetailInFaults is what you need I think.

UPDATE For the error you're getting

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.

It looks like you've got a mismatch between your server and client bindings. It's not that your XML is malformed, it's that it's not being sent in the format the server is expecting based on the server side binding configuration. You need to make sure that both the server and client are on the same binding type (basicHttpBinding or wsHttpBinding for example).

Client and service binding mismatch

Nick Ryan
  • 2,662
  • 1
  • 17
  • 24
  • Serialization exceptions are not handled by this attribute unfortunately. – Trident D'Gao Nov 26 '12 at 17:24
  • Ok, you say "I believe it has something to do with WCF not being able to serialize that result properly." but you are not sure. You need to enable diagnostics to find out what is going on. Regardless, it would be useful for you to include the exception detail in the faults while you are in development. – Nick Ryan Nov 26 '12 at 17:27
  • I am sure now it was a serialization problem. Find the update in the question body to get the details (actually the log record don't have any details which supports my point of not using it because it is useless). – Trident D'Gao Nov 26 '12 at 17:40
  • The log tells you *exactly* what was wrong. A mismatch in the binding expectation between the client and the server configuration. It's not a serialization issue at all. – Nick Ryan Nov 29 '12 at 14:44
  • I regenerated the client proxy (updated the service reference) many times trying to get rid of this misleading error message that blames bindings. And believe me with the latest and greatest proxy code, updated configuration and matching bindings (which I checked both on the server and client by hands by looking into the configuration files) it didn't help. So what you call "exactly wrong" in fact not so exact. As I said the problem was in the missing KnownType attribute which didn't prevent the proxy from being generated, but failed at serialization of the result on a call to the service. – Trident D'Gao Nov 29 '12 at 16:23
  • That is the exact root of the problem: http://stackoverflow.com/questions/8637652/wcf-charset-utf-8-of-the-response-message-does-not-match-the-content-type-of-the/13569437#13569437 – Trident D'Gao Nov 29 '12 at 16:25
0

In IIS, set your Application Pool Identity to Local System.

It did the trick for me.

spenibus
  • 4,339
  • 11
  • 26
  • 35
Arvin Sanaei
  • 103
  • 1
  • 12