In this second installment of “My Adventures with Silverlight” series, I will talk of how to successfully invoke a WCF service from Silverlight client.
In a nutshell: you have a Silverlight client application that wants to consume data available in a remote service. This service is hosted in a classic ASP.NET web service (.asmx) or, like in this example, in a Windows Communication Foundation (WCF) service (.svc).
Silverlight has a built-in support for invoking WCF services in System.ServiceModel namespace. You should add a reference to the WCF service from “Add Service Reference” option in your Silverlight project when it’s open in Visual Studio.
In this dialog box you specify the URL of the service you want to add.
If everything goes well, after clicking OK you should see the service referenced correctly:
After the service is referenced, you must instantiate a service proxy (a class which is created automatically when the service reference is added). Then, you invoke the service methods in the proxy. The proxy itself invokes those methods in the remote service, sending SOAP-encoded messages over the HTTP connection.
In order to successfully connect your Silverlight application to a WCF service, you should abide by some known restrictions.
The first limitation is that standard WCF services use wsHttpBinding binding configuration, which enables security and other enhancements. Silverlight 2 is currently limited to basicHttpBinding configuration, which doesn’t include them (but, in the other hand, is much more interoperable with non-WCF services). So, in order to successfully add a service reference, you should manually change the binding information in your service web.config file, as shown here:
Additionally, you must enable ASP.NET pipeline support in your WCF service. This is accomplished by adding a AspNetCompatibilityRequirements attribute to your WCF service class and adding a AspNetCompatibilityEnabled node in your WCF service web.config file.
If you use the standard Visual Studio WCF Service template, you will have to do these changes manually. If you use the Silverlight-enabled WCF Service template, these settings will be applied automatically.
Message Size Limit
If one of your service methods has a parameter that can grow in size, like a humble String, you need to know that the default service configuration in WCF has a limit somewhere around 7780 bytes of message size. A message bigger than that will throw a NotFound ---> System.Net.WebException. This exception is a catch-all generic exception when something goes wrong in communication with the WCF service. You will need a Http Debugging Proxy (more on that in next posts) to really dig out the real culprit.
To fix this you can follow the suggestion in Silverlight Official Forum:
- Change the binding entry in ServiceReferences.ClientConfig file of your Silverlight project to something like this:
<binding name\="BasicHttpBinding\_YourService" maxBufferSize\="2147483647" maxReceivedMessageSize\="2147483647"\>
- Add a new binding entry in system.ServiceModel node of the service web.config. Change the endpoint bindingConfiguration to use this new binding.
<binding name\="ServicesBinding" maxReceivedMessageSize\="2000000" maxBufferSize\="2000000"\>
<readerQuotas maxArrayLength\="2000000" maxStringContentLength\="2000000" />