Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Configuring WCF and IIS 7 With HTTP Bindings and Multiple Host Headers

Posted by Keith Elder | Posted in .Net, WCF | Posted on 28-04-2008

27

If you’ve tried to deploy Windows Communication Foundation (WCF)  in a production environment the odds are you have come across this error at one point or another:

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

It is one of those lovely errors that should have been gumped down before it made it into production code but for some reason the developer who wrote it thought they’d sound smarter if they obfuscated the problem to confuse everyone.  No fear, I’m hear to clear this up and gump it down to save you endless hours of time. 

The Problem

In multiple shared hosting environments or even in the enterprise where load balancers are used it isn’t uncommon to have a single machine answer to multiple host names.  This is typically the problem that causes the error above since IIS has more than one http binding configured to answer requests for a given web site.  To simulate this I am going to walk you through how to create a fake configuration so your local development machine answers to more than one host name.  Then I’ll walk you through how to configure IIS7 to deploy a WCF service to your local machine using one name, and then break the deployment to simulate the error above.  After that we’ll fix it.

Here is the overall goal of the walk through. 

  1. Configure our machine to answer multiple host names
  2. Setup IIS to support our application
  3. Deploy the sample WCF application
  4. Add the second host name to break the deployment
  5. Apply the fix

Requirements

A few months ago I did a walk through on how to configure WCF with multiple bindings.  We are going to take that example and deploy it into IIS.  I’ll be deploying this solution on Windows Vista SP1 using IIS7.  Even if you are using Windows Server 2008 the same setup should be similar.  If you haven’t read the previous article on multiple bindings please do so.  At the bottom of the article download the sample solution, this is what we’ll be deploying if you want to follow along.

Configuring Extra Host Headers

Edit hosts file to add fake names

More than likely if you are performing this setup on a developer machine for testing you’ll need to create several fake host names for your machine.  To do this, open the following file c:\windows\system32\drivers\etc\hosts and add in a few fake names.  For this example I’m going to add two additional host names for my machine so it answers to the names of “Elderville” and “WordsOfWisdom”.  You can obviously choose what you want.  Here are the two entries I am going to add to my hosts file.

image

Note that you will need to be administrator to add these lines to this file.  The lines added resolve to the localhost IP address which is 127.0.0.1.  After these names are added you should be able to ping these host names and get a response.

image

Locally the computer now responds to two additional host names:  elderville and wordsofwisdom.

Initial IIS7 Configuration

In order to deploy our sample WCF service we need to have a location pre-configured.   Create the following path on your hard drive called C:\WCFTest\wcfservice.  Once created, open Internet Information Services manager as administrator and right click the sites folder to add a new web site.

image

Create a new web site to deploy the WCF service and use the path we just created to deploy the service.  I’m going to configure the service to answer using the host name of elderville.

image

After the site is created, convert the “wcfservice” folder into an application.

image

image

This is as far as we need to go as this moment with IIS.  We’ll come back to IIS7 configuration in a bit so leave it open if you are following along.  Right now we just want to deploy the service and make sure it works.

Deploying Our Sample WCF Service

Unzip the sample solution and open the solution in Visual Studio 2008.  In order to prepare the service for deployment the only change we need to make is to change the address of the endpoints.  There are three endpoints this service exposes: WsPlain, Basic and WsSecured.  The first endpoint of WsPlain doesn’t have an address listed in the endpoint properties.  This means it takes the endpoint address it is deployed within.  Each endpoint must have a different address so to get around this we are going to use relative addresses. 

Open the WCF Configuration Editor by right clicking the web.config file in the project and change the address of the Basic and WsSecured endpoints to the same name.  Here’s what they should look like after you make the change.

image

image

Using relative addresses appends the string in the address field to the end of our service address therefore making a different address location for each endpoint.  For example.  Since we are deploying our service as http://elderville/wcfservice/service.svc, the basic endpoint address will get converted to http://elderville/wcfservice/service.svc/Basic

This is the only change that is needed to deploy this service.  Now right click the WCF project and click “Publish”.  Set the target location to c:\wcftest\wcfservice as seen below and then click publish.

image

Open Internet Explorer and browse to the following URL:  http://elderville/wcfservice/Service.svc.  You should see your service page.

image

Reconfigure Windows Test App

To test the service, remove the existing service location from the Windows test project included in the solution.  Open the app.config file and remove the existing WCF client information (leave just the configuration xml elements).  Right click on the service reference within the project and paste the new address into the address field then press go.  Once it loads the service, press OK to add the reference to the project.

image

Next launch the Windows Application and click on the binding buttons to see the messages going back and forth with your service. 

image

At this point we’ve just setup IIS7 and deployed a WCF service.  Steps 1-3 are now complete.  Now let’s apply a more real world scenario to see what happens.

Breaking The Deployment

Based on our original goals we are now going to break this deployment. This is the real heart of this problem as this simulates a more real world example. 

To break this deployment we are going to add the second host name to the WCFTest site we created.  This is simulating is a shared hosting environment or an enterprise setup where load balancers are used.  Since I created “wordsofwisdom” as my secondary host name I am going to add that as an additional HTTP binding on the application.  This means my application will now answer to two names.

In the IIS7 configuration manager right click the application and edit the bindings.

image

The site’s configured bindings should only have one binding enabled which is the original host name entered when the site was originally configured.

image

Click add and enter the second host name the computer will answer as.  I entered the secondary host name of “wordsofwisdom”.

image

Press OK and both names should appear within the site bindings list. 

image 

To recap what we just configured, we setup IIS7 to answer requests for both of our host names.  Again this isn’t uncommon to have this type of configuration.

Now open the browser and browse to the previous working service.  You should see the error now.

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

Since there are two names in the HTTP binding section it doesn’t know which one is the correct name to answer and thus the WCF service throws an exception. 

Fixing the Deployment

Depending on the .Net framework you are using the fix is different.  If you are using .Net 3.0 the only thing you can do to fix this is write a WCF custom ServiceHostFactory.   This work around is a little ugly and not something easy to standardize.  My suggestion is to upgrade to .Net 3.5 and take advantage of a new configuration option added in .Net 3.5 to solve this exact problem. 

The fix for .Net 3.5 uses a  new configuration element called <baseAddressPrefixFilters>

Represents a collection of configuration elements that specify pass through filters, which provide a mechanism to pick the appropriate Internet Information Services (IIS) bindings when hosting the Windows Communication Foundation (WCF) application in IIS.  A prefix filter provides a way for shared hosting providers to specify which URIs are to be used by the service. It enables shared hosts to host multiple applications with different base addresses for the same scheme on the same site.

To apply this fix open the web.config file for the service within Visual Studio and within the <system.serviceModel> tags add the following XML:

<serviceHostingEnvironment>
    <baseAddressPrefixFilters>
        <add prefix="http://elderville/wcfservice"/>
    </baseAddressPrefixFilters>
</serviceHostingEnvironment>

Once these lines are added, redeploy the service and refresh the service in the browser.  The error should be gone!

Conclusion

In this walk through we’ve covered a lot!  We walked through how to configure IIS7 and deploy an existing WCF service.  We also looked at the scenario that causes the error that a lot of developers run into when deploying WCF services in various environments.  The moral of this story is be safe and go ahead and plan on adding the baseAddressPrefixFilters tag into your web.config files from now on since you never really know how administrators will configure their servers. 

I hope you enjoyed this walk through.

Speaking at Lower Alabama User Group in May

Posted by Keith Elder | Posted in Presentations, Speaking | Posted on 26-04-2008

0

I will visiting the Lower Alabama .Net User Group on May 27th presenting a talk on Windows Workflow Foundation.  Here are the details:

Location:
  Office Mall South
  3100 Cottage Hill Road
  Building 3
  Mobile, AL 36606

Time:
  May 27th, 2008, 6:00 PM

Topic: Introduction to Workflow Foundation

Foundation Scenario: Your boss gives you a task with fairly complicated business rules one day at work. You spend weeks coding it and as soon as you get done he/she informs you the business rules have changed. Your first thought is to lash out at your boss because this is a major change. Instead you politely smile and say thank you, “I’ll get right on it”. Little does your boss know you’ve used Workflow Foundation to map out all the business logic and rules. You quickly make the change declaratively within Workflow Foundation and all of a sudden you are a hero.

Workflow Foundation enables developers to quickly and easily map out complex business tasks that turn their code into declarative models. In this session we’ll explore the ins and outs of Workflow Foundation from the ground up so you’ll have a good sense of where to get started when you head back to the office. 

Slide deck is available for download.

Video of Me Singing Rockaroake at the MVP Summit

Posted by Keith Elder | Posted in Funny Stuff, Videos | Posted on 23-04-2008

2

What better way to end the MVP Summit than to have a really cool party at the Experience Music Project|Science Fiction Museum and Hall of Fame in Seattle, WA.

Joe Healy sent me the video he of me signing on stage during Rockaroake while I was on stage singing a little Garth Brooks, Friends in Low Places (link below).  It was a blast!  Some of you may have heard rumors about how I broke “Rockaroake” that night but really I didn’t break anything.  Here is Jim’s quote:

Seeing Keith Elder get on stage and sing karaoke (and break the process) nearly paid the price of admission for me.

The back story is right when we hit the first verse of the song Ryan Olshan jumped on stage to join in the chorus.  The only problem was he was, well…. he was a little too happy at the moment to join in.  Right behind him was Javier Lazano, his wife, Nick Parker and his wife.  As soon as everyone hit the stage the band stopped playing and everything shut down.  Basically the MC said no fun was allowed and that everyone can’t come up on stage and for everyone to get off the stage.  Ok, so maybe I broke it a little.  The band then restarted the song.  John Kellar and Jason Follas were in the back of the room dying laughing and thus John tweeted:

image

Very funny John!  Of course I didn’t break it.  I guess the MC did.  Anyway.  It was a blast.  Here is the video of the performance after things got going again.  Enjoy.

image

Silverlight Link to video: http://keithelder.net/videos/mvpsummit2008/default.html

Media:  http://keithelder.net/videos/mvpsummit2008/SongsOfWisdom.wmv

 

Video: Dustin Campbell Eating Tuna

Posted by Keith Elder | Posted in Funny Stuff | Posted on 19-04-2008

2

Dustin, sorry, but I had to share this video with everyone because I saw you eat at least twenty pounds of  tuna fish over the course of the MVP Summit.  Consider it a farewell tribute since you joined Microsoft. 

The video was taken at the EMP museum in Seattle, WA on April 16th, 2008.

Technorati tags: , ,

MVP Geek Lager Pictures

Posted by Keith Elder | Posted in Uncategorized | Posted on 19-04-2008

2

Thursday night we gathered at Kell’s Irish Pub and Restaurant one last time before heading home from Seattle.  There was an unofficial count of about 75 of us that gathered for food and chatter.  It was certainly a lot more than last year and we had a blast.  Thanks to everyone that came out and we’ll try to do it again next year!

Pictures from the Geek Lager are here:

http://flickr.com/photos/keithelder/sets/72157604621823612/