Silverlight: How to Make Your WCF Web Service Work for All Users

Specification of the Problem

A WCF web service works when a user types site in his browser with www in the name:

· Works OK!,


but it stops working if the same site is typed without www:

· Fails with error message:

“The remote server returned an unexpected response: 404 Not Found”


Note: the samples in this article are using Silverlight 2 Beta 2.

Why is This Happening?

WCF Web services work currently with one base Uri only. Some website hosts (if not most) pass 2, 3 or more base Uri-s to a web service when they activate it.

For example for the above web service the based addresses passed during activation may look like this:

If we don’t do anything special to filter the base addresses, our web service creation will fail. If I remember correctly, the error message looks like this:


This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.

Parameter name: item


To work around this issue, I create a custom ServiceHostFactory and return only one base address:

public class MyServiceHostFactory : ServiceHostFactory {

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) {

        return new CustomServiceHost(serviceType, new Uri(" "));



public class CustomServiceHost : ServiceHost {

    public CustomServiceHost(Type serviceType, params Uri[] baseAddresses)

        : base(serviceType, baseAddresses) { }

    protected override void ApplyConfiguration() {





Read more about the custom factory here:


Because we can return only one address, our service is usable only from this address. That’s why when I type I got the above error message.

One Way to Fix It

I’ve posted the not working code of the WCF Service here:


Let’s fix it!

The fix that I will apply is to create a second .svc file and create a custom factory for the non-www address in it. Then I’ll programmatically call one service or the other from within the Silverlight Client App, based on what address the user typed in their browser.


Step 1: Create ServiceNoWww.svc

Copy-paste in Solution Explorer Service.svc and rename it to ServiceNoWww.svc

Change its factory specification to:


Step 2: Create custom factory for the ServiceNoWww.svc in code behind

Open App_Code/Service.cs and add (don’t change the existing one) this text:


public class MyServiceHostFactoryNoWww : ServiceHostFactory {

    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) {

        return new CustomServiceHost(serviceType, new Uri(""));




Note that I removed the www. before and named the class same using the same name specified in ServiceNoWww.svc


Step 3: Change the client app to switch between the two services transparently

Replace the service instantiation code in Page.xaml.cs.


client = new ServiceClientApp.ServiceReference1.ServiceClient();


Binding defaultBinding = new System.ServiceModel.BasicHttpBinding();

EndpointAddress defaultAddress;

if (HtmlPage.Document.DocumentUri.AbsoluteUri.ToLower().Contains("www."))


    defaultAddress = new System.ServiceModel.EndpointAddress("");




    defaultAddress = new System.ServiceModel.EndpointAddress("");


client = new ServiceClientApp.ServiceReference1.ServiceClient(defaultBinding, defaultAddress);


            client = new ServiceClientApp.ServiceReference1.ServiceClient(defaultBinding, defaultAddress);


Note: you don’t have to add reference to the second service in your app, only change the default address using the above code.