none
How to debug deserialization errors? RRS feed

  • Question

  • I've got a service running under a Windows Service, using netTcp, under Beta 2/May. I'm trying to send a parameter that's defined like this:

    [Serializable]
    public class Container
    {
       private byte[] m_Data;
       public byte[] Data { get {...}  set {...} }

       private Descriptor m_Descriptor;
       public Descriptor Descriptor { get {...} set {...} }
    }

    The get/set methods are simple accessors, and the Descriptor is a simple class, also marked as [Serializable], that has several string, int and Enum members.

    Usually my call, which sends an array of Containers to the service, works without a problem. Sometimes, though, I get this FaultException on the client:

    The formatter threw an exception while trying to deserialize the message: Error while trying to deserialize parameter http://tempuri.org/:data. There was an error deserializing the object of type MyProject.Container[]

    This happens even when I'm sending only one Container, and usually tends to happen when the Data byte-array is relatively large. Even so, I've seen it happen with an 18k array, while my service (set to default settings) should be able to accept 64k messages.

    My question isn't so much why this is happening as much as how can I debug these errors? It's an error that happens during WCF's deserialization phase before it calls my service instance, so I can't put a breakpoint or even catch the exception when debugging. The exception gives very little information - there's no inner exception - and I'd like to be able to "catch it in the act", so to speak.

    Anyone know how I can do this?

    Sunday, July 23, 2006 4:08 PM

Answers

  • Have you looked at the SvcTraceViewer.exe utility? I would dump the entire XML message for a successful and unsuccessful message, and compare the messages for something suspect in deserialization. Furthermore, the trace statements leading up to the exception may also help you to trouble-shoot, and you'll see those in the errors reported during message tracing.

    To enable tracing for your service, put this into your service host config, inside <system.serviceModel> (note: this is June CTP syntax):

    <diagnostics performanceCounters="All" wmiProviderEnabled="true" >

    <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="100000" />

    </diagnostics>

    Then in the <configuration> section add this (make sure you have the correct path where logs can be saved):

    <system.diagnostics >

    <sharedListeners>

    <add name="sharedListener"

    type="System.Diagnostics.XmlWriterTraceListener"

    initializeData="c:\logs\servicetrace.svclog" />

    </sharedListeners>

    <sources>

    <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" >

    <listeners>

    <add name="sharedListener" />

    </listeners>

    </source>

    <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">

    <listeners>

    <add name="sharedListener" />

    </listeners>

    </source>

    </sources>

    </system.diagnostics>

     

    Then, open the logs in the svctraceviewer.exe tool.

    For May CTP, I believe the only change is that you change performanceCounters="All"  to performanceCountersEnabled="true" . You might also change the name of the service trace file to .log instead of .svclog to make loading in the tool easier.

     

     

     

    Sunday, July 23, 2006 6:52 PM
    Moderator
  • Increase your maxArrayLength reader quota for the binding configuration on both service and client. The default is 16K.

    <bindings>
       <netTcpBinding>
          <
    binding name="AllowLargeMessages" maxReceivedMessageSize="512000" maxBufferSize="512000">

    <readerQuotas maxArrayLength="5000000" />

    </binding>

       </netTcpBinding>
    </
    bindings>

     

    Sunday, July 30, 2006 4:29 PM
    Moderator

All replies

  • Have you looked at the SvcTraceViewer.exe utility? I would dump the entire XML message for a successful and unsuccessful message, and compare the messages for something suspect in deserialization. Furthermore, the trace statements leading up to the exception may also help you to trouble-shoot, and you'll see those in the errors reported during message tracing.

    To enable tracing for your service, put this into your service host config, inside <system.serviceModel> (note: this is June CTP syntax):

    <diagnostics performanceCounters="All" wmiProviderEnabled="true" >

    <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="100000" />

    </diagnostics>

    Then in the <configuration> section add this (make sure you have the correct path where logs can be saved):

    <system.diagnostics >

    <sharedListeners>

    <add name="sharedListener"

    type="System.Diagnostics.XmlWriterTraceListener"

    initializeData="c:\logs\servicetrace.svclog" />

    </sharedListeners>

    <sources>

    <source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" >

    <listeners>

    <add name="sharedListener" />

    </listeners>

    </source>

    <source name="System.ServiceModel.MessageLogging" switchValue="Verbose">

    <listeners>

    <add name="sharedListener" />

    </listeners>

    </source>

    </sources>

    </system.diagnostics>

     

    Then, open the logs in the svctraceviewer.exe tool.

    For May CTP, I believe the only change is that you change performanceCounters="All"  to performanceCountersEnabled="true" . You might also change the name of the service trace file to .log instead of .svclog to make loading in the tool easier.

     

     

     

    Sunday, July 23, 2006 6:52 PM
    Moderator
  • Excellent - this is exactly the trace information I wanted.

    Thanks!

    Monday, July 24, 2006 10:07 AM
  • Sorry for bumping the thread, but even the amazingly verbose log files that I now generate don't seem to help. When I'm sending the class described above over a NetTcp connection, I get unexplained Fault Exceptions:

    "The formatter threw an exception while trying to deserialize the message: Error while trying to deserialize parameter http://tempuri.org/:data. There was an error deserializing the object of type Afcon.Pcim.Common.ProjectData.ProjectDataContainer[]"

    This seems to happen when my 'data' parameter, the byte array, is above a certain size. I've gradually shrunk the block until I've found the cut-off point to be around 15k of data (plus whatever the rest of the object takes up, plus the headers)

    I have this bindingConfiguration set up in my server's app.config file, which should allow my service to receive large messages, I believe:

    <endpoint address="net.tcp://localhost/ProjectData" binding="netTcpBinding" contract="IProjectDataService" bindingConfiguration="AllowLargeMessages"> </endpoint>

    <bindings>
       <netTcpBinding>
          <
    binding name="AllowLargeMessages" maxReceivedMessageSize="512000" maxBufferSize="512000"/>
       </
    netTcpBinding>
    </
    bindings>

    So what am I missing here?


     

     

    Sunday, July 30, 2006 4:22 PM
  • Increase your maxArrayLength reader quota for the binding configuration on both service and client. The default is 16K.

    <bindings>
       <netTcpBinding>
          <
    binding name="AllowLargeMessages" maxReceivedMessageSize="512000" maxBufferSize="512000">

    <readerQuotas maxArrayLength="5000000" />

    </binding>

       </netTcpBinding>
    </
    bindings>

     

    Sunday, July 30, 2006 4:29 PM
    Moderator
  • That seems to have done the trick, though I remain perplexed.

    It seems that wanting to increase the maximum message size requires at least three distinct settings to be set, which is rather confusing. One to set the total acceptable size, one to set the buffer so it can handle that message, and one to set the maximum size for a field - configuration of WCF services seems to get MORE complex, rather than less. I hope there's work on simplifying this before RTM.

    Incidently, the June Documentation CTP claims that maxArrayLength is set to Int32.MaxValue by default.

    Sunday, July 30, 2006 4:47 PM