Logo HeaderGraphic
"... A Yankee in the Land of The Long White Cloud, Aotearoa ..."

Xml Serialization in WCF 

image

So I have been working with a client for a while (say 3+ years…) on a WCF application.  Yes, you read that correctly 3 years, which of course if you know your WCF history, means I’ve been working with it since release 1.0.  The joy of being a pioneer in front [arrows in the back].  Anyways, about 2 months ago as we were finally rolling out the application to a Beta Client, we found a problem, as you can see from above.

There is a limit to how much data you can push down WCF thru simple http protocol.  We were promised back in the day, that we wouldn’t have to worry about stuff like this, just pass our objects to WCF (making sure that they are serializable, and WCF would take care of the details of moving it.  Well of course the devil is in the details, and our client had a chunk of data to be sync’d that found the devil.  Turns out that WCF won’t take care of everything.  Hey no problem, just increase that thing they tell you to increase, right? 

Actually it really is that easy… except for WCF configuration is a nightmare.  I’ve been doing this thing for 3 years, and I STILL have to think about it. and I still get confused, here take a look at this relatively simple file. And remember this is only ONE SIDE.  Checkout all the values that have to do with sizing, and where exactly do I put / modify that MaxItemsInObjectGraph?

<system.serviceModel>
    <services>
        <service behaviorConfiguration="SynchronizationServiceBehavior"
         name="Bst.Rincon.DataExportImport.Services.Controller.ControllerSynchronization">
            <endpoint address="" behaviorConfiguration="SynchronizationEndpointBehavior"
             binding="basicHttpBinding" bindingConfiguration="SynchronizationBinding"
             name="SynchronizationEndpoint" contract="Bst.Rincon.DataExportImport.Contracts.Service.Controller.IControllerSynchronization" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
    <behaviors>
        <endpointBehaviors>
            <behavior name="SynchronizationBehavior">
                <callbackDebug/>
            </behavior>
            <behavior name="SynchronizationEndpointBehavior"/>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior name="SynchronizationServiceBehavior">
                <serviceDebug includeExceptionDetailInFaults="true"/>
                <serviceMetadata httpGetEnabled="true"/>
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <bindings>
        <basicHttpBinding>
            <binding name="SynchronizationBinding" maxReceivedMessageSize="2000000" maxBufferSize="2000000" >
                <readerQuotas maxArrayLength="2000000" maxStringContentLength="2000000"/>
            </binding>
        </basicHttpBinding>
    </bindings>
    <client>
        <endpoint address="http://localhost/RinconServicesSatellite/Synchronization.svc"
         behaviorConfiguration="SynchronizationBehavior" binding="basicHttpBinding"
         bindingConfiguration="SynchronizationBinding" contract="ISatelliteSynchronization"
         name="FellingSatellite" />
     </client>
</system.serviceModel>

(in case you are wondering, you need to modify the serviceBehavior on the one sending it out, and the endpointBehavior on the one receiving

<serviceBehaviors>
    <behavior name="SynchronizationServiceBehavior">
        <serviceDebug includeExceptionDetailInFaults="true"/>
        <serviceMetadata httpGetEnabled="true"/>
        <dataContractSerializer maxItemsInObjectGraph="2147483647" />
    </behavior>
</serviceBehaviors>

Even the WCF configuration tool included in the windows sdk is no great help.

image

Where would you go here to specify it? 

image

Well in this case you are concerned with the Behaviors nodes

image

Select the BehaviorConfiguration node for one of the ends (in this case let’s do the listener [which = endpoint] )

image

now on the right side of the form you click the Add Button.

which gets you this dialog

image

Remember now, you are trying to specify MaxItemsInObjectGraph… so which one do you pick?  Well in this case with a little thinking it might occur to you that since we are talking about serialization, perhaps the dataContractSerializer is the correct place to start, but don’t feel  bad if it didn’t occur to you to start with, it didn’t occur to me either, I had to Google it.

Ok now add the add button, and what do you get?

image

Great, that added the element extension, but what next?  Well you have to actually select the node, and when you have done that, you can finally modify the entry!

image

image

MUCH TOO HARD and obscure, WCF will never become a mainstream product for the average business / in-house programmer until this thing is much easier to administer.

Well that unfortunately didn’t solve my problem (all those other size limits are coming into play – look back at the config file example above).  There is nothing for it, for best reliability I will have to programmatically “chunk” up the data and send it over in small packets.

Good WCF developing


Post Script

Well after kicking up all the sizes on all the protocols, this is what I get

image

So obviously, this won’t be my last entry on WCF.

Digg This
 
Posted on 27-Mar-09 by Matthew C. Hintzen
Bookmark this post with:        
Tags: