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.
Where would you go here to specify it?
Well in this case you are concerned with the Behaviors nodes
Select the BehaviorConfiguration node for one of the ends (in this case let’s do the listener [which = endpoint] )
now on the right side of the form you click the Add Button.
which gets you this dialog
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?
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!
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
So obviously, this won’t be my last entry on WCF.