If you happen to develop a WCF service that needs to deliver large amount of data to your Silverlight application, you might run into the problem that the data will never reach your application but instead you might just get an exception like „System.Net.WebException: The remote server returned an error: NotFound„.
There are two possible reasons for this:
- The transfer mode of your service being set to „Buffered“ and the size of the data being transferred is bigger than the buffer size.
- There are two many items to be serialized and deserialized by the DataContractSerializer.
Important: Before you change the configuration and behaviour of your service, make sure your understand the security related issues, e.g. as described in the MSDN: Security Considerations for Data.
If the transfer mode of your service is set to „Buffered“ (which is default), the entire message is hold in a message buffer until the transfer is complete. If the size of the data is bigger than the buffer, the data can not be transferred. In streamed mode only the message headers are buffered. Actually, there are 4 possible modes to choose from for the transfer mode. You can decide either to stream the data in both direction or only in one. Besides setting the transfer mode to streamed, there is also the possibility to increase the buffer size. See the corresponding MSDN page for more information about transfer modes.
So how to you actually change the transfer mode to streamed for transferring responds? You can do this either in code or in the web.config file where your service is configured. Here we cover only the case of configuring it in the web.config file. To change the transfer mode you have to add a binding configuration to your web.config file as part of the <system.serviceModel>section:
<bindings> <basicHttpBinding> <binding name="StreamedResponseBinding" transferMode="StreamedResponse"/> </basicHttpBinding> </bindings>
After you have defined your custom binding configuration, you have to apply this configuration to the binding of your service:
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="StreamedResponseBinding" contract="YourServiceContract"
That’s it. Now your response is streamed back to the client instead of being buffered. The client code does not need be changed.
Data sent back to the client by a WCF service is serialized and deserialized by the DataContractSerializer class. By default this class limits the number of objects that are serialized in one call to Int32.MaxValue. However, if you have many objects (e.g. a long list of strings or other custom DataContracts) to be returned to the client, the number of objects can exceed this limit. In this case your client will receive an error similiar to this one:
There was an error while trying to deserialize parameter http://tempuri.org/:<YourMethodName>. The InnerException message was ‚There was an error deserializing the object of type <YourResultType>. Unexpected end of file has occurred. The following elements are not closed …
If you in any case need to send more objects back, you can increase this limit by setting the DataContractSerializer::MaxItemsInObjectGraph property. This property can be set in the behaviour configuration of your service in the web.config file:
<behavior name="YourServiceBehaviourName"> ... <dataContractSerializer maxItemsInObjectGraph="6000000" /> </behavior>
Adapt the value of maxItemsInObjectGraph to your needs.
That’s it. Now you should be able to also tranfer very big amount of data back to your Silverlight application.