WCF and large messages

This week I’ve been training a couple of people on how to use .NET, WCF4, Entity Framework 4 and other technologies to build an Enterprise Application. One of the things we did was return all rows from a table, and this table contains about 2500 rows. We’re using the Entity Framework 4 self-tracking entities which also serialize all changes made it the objects.

And I kept getting this error:

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)

image

At first I thought it was something to do with the maximum message size, another kind of error you get when sending large messages.

The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.

Server stack trace:
   at System.ServiceModel.Channels.HttpInput.ThrowMaxReceivedMessageSizeExceeded()
   at System.ServiceModel.Channels.HttpInput.GetMessageBuffer()
   at System.ServiceModel.Channels.HttpInput.ReadBufferedMessage(Stream inputStream)

image

This one is easy to fix (although a little confusing because you have to configure the binding of the receiving side of the message, which is most of the time the client:

image

But doing this didn’t help. So what was it? I knew the size of the message couldn’t be the problem, because I’d sent way bigger messages before. Maybe there was something in the contents that made the DataContractSerializer crash? Checking this is easy, I wrote a little code that would make the serializer write everything to a stream and see what happens. Works fine. Hmmm. What could it be? So I went over the list of properties of the DataContractSerializer. I has a MaxItemsInObjectGraph property. Maybe that was it, but how can I change this number? Looking at the behaviors I found it. What you need to do when you send a large number of objects is you have to increate this number, which is easy.

At the server side you use the DataContractSerializer service behavior and set its value to a large enough number:

image 

At the clients side you use the DataContractSerializer endpoint behavior.

That fixed my problem.