Publishing WCF web services for Silverlight.

As a self-confessed crayon wielder I tend not to get involved in the washing machine technology of web services.  I am normally a consumer only and when I do have to write a web service it has only been part of prototypes or proof's of concept.

The current project I am on required something a little more.  We were required to develop and publish a web service that could be consumed by a Silverlight application from our live site.

The development process was fairly easy.

Deployment not so.

You'll probably have noticed that when developing a WCF service, when you view the service in a browser you get something like this.

https://www.localhost:10946/Services/MyService.svc?wsdl

You'll notice that 'localhost' is returned for the hostname both on the documentation pages and in the WSDL.

What you may not know is that if you deploy this to a public web service the documentation and WSDL will use the internal hostname of whatever server you deploy it to.  Which, in our case anyway, wasn't the same as the public hostname. This leads to both a security risk and the web service not working as the wsdl refers to a non-resolvable host.

We went through loop after loop trying to solve this problem.  Pretty much everyone I spoke to recommended calling a couple of functions exposed by adsutil.vbs which you'll find in the AdminScripts folder under inetpub.

cscript //nologo %systemdrive%\inetpub\adminscripts\adsutil.vbs set W3SVC/1/ServerBindings “:80:wwwmydomain.com”

and

cscript //nologo %systemdrive%\inetpub\adminscripts\adsutil.vbs set W3SVC/1/UseHostName false

It appears that these commands are a legacy from pre-IIS6 as all they seem to do is add a host header to the web site.

As an aside, (and why this article mentions Silverlight) is that just deploying a static WSDL file and pointing the Visual Studio 'Add Service Reference' feature at it from a Silverlight 2 project doesn't manage to create a proxy correctly.

Whilst this works for a single hostname, if, like us, you have a number of redirects (for example different top level domains) pointing to the same site then you need to add a host header for each redirect.  (Or as we found out, one host header for your web service location and an empty host header to cater for the rest - the web service host header needs to be first though)

image

This will lead you to another problem.  WCF services won't work if you have more than one host header.

There's two ways of solving this.

First you can add a ServiceHostFactory that strips out the other host headers and only adds the first. (This works because regardless of the domain that your users come from the location of the service can always be the same).

Otherwise (if you are using .NET 3.5) you can use the baseAddressPrefixFilters config section.

Technorati Tags: Silverlight,WCF,IIS,hostheader,servicehostfactory,baseaddressprefixfilters