Although I’ve done a fair amount with WCF, it’s been mostly around hosting services in end-user applications or in Windows services. Every time I’ve tried to host a WCF service in IIS, things suddenly got very complicated and I seemed to spend a lot of time troubleshooting. Well today, I needed to host a WCF service in IIS and ran across such a problem:
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.
What does that mean? Well, I know the service just sort of piggy-backs on the port and virtual application of the ASP.NET app, so I assumed that the service would get its address and port from IIS. Well, after some digging around a bit, I found this blog post: http://www.robzelt.com/blog/2007/01/24/WCF+This+Collection+Already+Contains+An+Address+With+Scheme+Http.aspx
The problem occurs when the service is hosted in IIS, and that IIS server has multiple IP addresses assigned. This results in multiple baseAddresses. The answer is to create a custom service host. The blog post above didn’t go into all the detail, so I wanted to write this down (mostly for my own benefit), here.
<compilation debug="true" targetFramework="4.0" />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
Service (ExampleService) and Contract (IExampleService) – NO CHANGE
public class CustomServiceHost : ServiceHost
public CustomServiceHost(Type serviceType, params Uri baseAddresses)
: base(serviceType, baseAddresses)
protected override void ApplyConfiguration()
public class CustomServiceHostFactory : ServiceHostFactory
protected override ServiceHost CreateServiceHost(Type serviceType, Uri baseAddresses)
CustomServiceHost customServiceHost =
new CustomServiceHost(serviceType, baseAddresses);
<%@ ServiceHost Language="C#" Debug="true"
Service="SederSoftware.WcfExample.ExampleService" CodeBehind="ExampleService.svc.cs" %>
So to piece this all together… When you invoke the ExampleService.svc, it calls the "Factory" specified – CustomerServiceHostFactory. That factory attempts to start a service host – and it specifies just ONE of the IP addresses. Arguably, you could add some logic here to filter which one/ones you want to run from, but for my purposes, just pulling the first one is fine.
From that point on, the rest is like a regular WCF service. So there – you’re welcome, Future Robert, who is not going to remember this in a couple of weeks! Also, the problem I worked with today was with VS2005 and .NET 3.0 – and I just tried this now with .NET 4.0 and it works fine for both.