Setting Maximum Object Size in WCF
I have recently been working on a Silverlight application that uses WCF for all data access functions.
The application worked fine on my development machine but when I moved it over to a test environment I received the following, rather vague, error when making a few of the database calls:
The remote server returned an error: NotFound
After some debugging I realised that this happened when data being returned to the Silverlight application was too large, I then found the inner exception was:
Maximum number of items that can be serialized or deserialized in an object graph is ‘65536’. Change the object graph or increase the MaxItemsInObjectGraph quota
The fix for this involves changing the MaxItemsInObjectGraph property for the service in both the client and the server code.
Server Side
The server side change is done within the web.config file of the web application that is hosting the Silverlight application. Add the following tag to the behavior tag for the misbehaving service:
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
This sets the maxItemsInObjectGraph = to Int32.Max. Now the fill behavior tag should look something like:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyService.Service1Behavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647" />
</behavior>
.....
Client Side
I made the client side change in the code behind page within my Silverlight application. I added a service reference to the above WCF service, Service1, and rather than just declaring a new instance of Service1 the way I was originally doing it, like:
private Service1Client myService = new Service1Client();
I altered the declaration of my Service1Client variable to be:
private Service1Client _myService;
private Service1Client myService
{
get
{
if (_myService == null)
{
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
binding.MaxReceivedMessageSize = 2147483647;
Uri serviceUri = new Uri(App.Current.Host.Source, "../Service1.svc");
_myService = new Service1Client(binding, new EndpointAddress(serviceUri));
}
return _myService;
}
}
In the above code I manually declare a BasicHttpBinding object and set it’s MaxReceivedMessageSize to Int32.Max
(default 65,536).
Using Int32.Max
for these values is slightly overkill but it shows how you can limit the amount of data being passed from your service.