Self-Hosted WCF Service for Silverlight

Visual Studio 2010 includes the ability to build new projects based on project templates published to the Visual Studio Gallery. I published a template that includes the necessary configuration and classes to quickly build a self-hosted WCF service library for Silverlight clients. The template can be found in the “WCF” and “Silverlight” categories of the Visual Studio Gallery.

clientaccesspolicy.xml

The primary difference in my project template and the standard WCF service library template is the service contract and implementation method to serve the “clientaccesspolicy.xml” file required for cross-domain service calls from Silverlight clients. This file is automatically downloaded by the Silverlight runtime when the application attempts to access a network resource. If you were to host your service in IIS you would simply place the policy file on the root of the web server. However, since there is no web server when you self-host your services, this template uses the System.ServiceModel.Web.WebGetAttribute class to specify a web method to handle the request for the policy file.

[ServiceContract] public interface IClientAccessPolicy
{
    [OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")] Stream GetPolicy();
}

The GetPolicy() method will return a stream containing the contents of the policy file. The specific policy you wish to enforce should be specified as part of the string built and returned in this method.

System.IO.Stream IClientAccessPolicy.GetPolicy()
{
    // TODO: Modify the string below to set the desired cross-domain policy
    string result = @"<?xml version=""1.0"" encoding=""utf-8""?> <access-policy> <cross-domain-access> <policy> <allow-from http-request-headers=""*""> <domain uri=""http://*""/> </allow-from> <grant-to> <resource path=""/"" include-subpaths=""true""/> </grant-to> </policy> </cross-domain-access> </access-policy>"; WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
    return new MemoryStream(Encoding.UTF8.GetBytes(result));
}

App.config

The default App.config file included with the template has been modified from the original service library config file in a few important ways. It includes an endpoint configured for the binary encoding released with Silverlight 3. This is implemented as a custom binding. Also, there is an endpoint for the service contract which defines the GetPolicy() method to serve the policy file. It is configured to use the WebHttpBinding class and has an endpoint behavior configured with the element to enable the WCF web programming model. Finally, the base address for the service has been modified so that it now only specifies a server (localhost) and port number (8732) to use as a base address. The default service template adds a path to the base address URL beginning with “DesignTimeAddresses”. The base address must specify the root of the server since that is where the Silverlight runtime will look for the clientaccesspolicy.xml file.

<bindings> <customBinding> <binding name="binaryHttpBinding"> <binaryMessageEncoding /> <httpTransport /> </binding> </customBinding> </bindings> <services> <service name="SLServiceLibrary.Service1" behaviorConfiguration="SLServiceLibrary.ServiceBehavior"> <endpoint address="Service1" binding="customBinding" contract="SLServiceLibrary.IService1" bindingConfiguration="binaryHttpBinding" /> <endpoint address="" binding="webHttpBinding" contract="SLServiceLibrary.IClientAccessPolicy" behaviorConfiguration="webHttpEnablingBehavior" /> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:8732/" /> </baseAddresses> </host> </service> </services>

Console Host

The template includes a second project called “ConsoleHost” which is simply a console application configured to host the service. The App.config file for the host project is identical to the one in the service library project with the exception of it using a different port number in the base address (8733). In a production environment it would almost certainly be preferable to host the WCF service in a Windows Service. However, a console application is much more convenient when debugging in Visual Studio.

The console host application should be configured as the default start-up project when debugging in Visual Studio. When the project is run you should be able to type the following address in a browser and receive the contents of the clientaccesspolicy.xml “file”:

http://localhost:8733/clientaccesspolicy.xml

You will then be ready to add a Silverlight application to the solution and create a service reference from it to your new self-hosted service and use it as you would any other service for Silverlight clients.

Enjoy.

Author image
About Brice Wilson