The root of the problem was that we had only implemented one Endpoint, using the WSHttpBinding. This was great for any clients running .NET 3.0 or later, but this binding doesn't provide any backwards compatibility for clients running a framework earlier than .NET 3.0.
Endpoint Comparison Chart (plus Client .NET Framework column)(This comparison chart was created by Aaron Skonnard and the original can be found here: http://www.pluralsight.com/community/blogs/aaron/archive/2007/03/22/46560.aspx)
So the answer seems simple enough right? If I need .NET 2.0 clients to connect to my WCF web services then all I need to do is to add an Endpoint that uses the BasicHttpBinding and voila, I should be good to go right? Wrong - that is where my troubles started.
WSHttpBinding vs. BasicHttpBindingThere are some MAJOR differences between the two bindings and for all intents & purposes you should stay away from using the BasicHttpBinding whenever possible. However in some cases (like the one I found myself in) you need that backwards compatibility with .NET 2.0 clients and the BasicHttpBinding is the only way to get it. I would only recommend using the BasicHttpBinding in an intranet scenario however & in conjunction with Windows Authentication.
A great article on the differences between the bindings can be found here: http://www.topxml.com/rbnews/WSCF/WCF/re-89303_WCF---BasicHttpBinding-compared-to-WSHttpBinding-at-SOAP-packet-level-.aspx
A great post on how to use Windows Authentication with the BasicHttpBinding can be found here: http://www.rickgaribay.net/archive/2007/04/04/recipe-wcf-basichttpbinding-with-windows-authentication.aspx
NOTE: I am writing a follow up post on getting the BasicHttpBinding with Windows Authentication and a .NET 2.0 client.
Creating Multiple WCF EndpointsSo according to this article: http://www.devx.com/codemag/Article/33655/1763/page/4 adding an Endpoint that uses BasicHttpBinding should be fairly straight forward & easy. I would end up with something like this:
In cases where you might want to expose multiple endpoints for the same .svc endpoint, you can use relative addressing. This example illustrates a case where clients can access the same Service.svc endpoint using BasicHttpBinding or WSHttpBinding to support different Web service protocols. The <endpoint> configuration for the service uses relative addressing, appending "/Soap11" and "/Soap12" to the endpoint address:Ok, great, no problemo. I just need to add an Endpoint that uses the BasicHttpBinding and assign it's address attribute a value. To simplify things, I created a quick test WCF Service host & a client (both are downloadable at the bottom of this post.)
<service name="HelloIndigo.HelloIndigoService" > <endpoint address="Soap11" contract="HelloIndigo.IHelloIndigoService" binding="basicHttpBinding"/> <endpoint address="Soap12" contract="HelloIndigo.IHelloIndigoService" binding="wsHttpBinding"/> </service>
Clients address each service endpoint in this way:
And based on the articles I read my client svc URIs should look like this:
(the 12345 will be replaced by whatever dynamic port number the built in Visual Studio host assigns when you run the host locally.)
Will The Real URI Please Stand UpSo since we added endpoint address attributes to all of our endpoints and we have different URIs now for each endpoint we should use the new URIs when trying to connect to our services right? Wrong.
Even though you now have different URIs for each endpoint, you still use the base ".svc" URI when connecting clients to the service. I.E. to connect to the BasicHttpBinding Enpoint you would use
and to connect to the WsHttpBinding Endpoint you would also use
When you add a reference to these endpoints using Visual Studio a client connection will actually be specified for both endpoints if you are adding a Service Reference. If you are adding a Web Reference a connection will be configured for the BasicHttpBinding endpoint only as it is the only endpoint the Web Reference is compatible with.
Example client web.config Endpoint configurations:
Notice that even though you used the base .svc URI to address the web service, svcutil.exe created proxy classes to connect to both endpoints using the full address of each endpoint
Client CodeHere is the sample code that connects to the WsHttpBinding & BasicHttpBinding Endpoints using the proxy created by svcutil.exe and the code that connects to the BasicHttpBinding using the proxy created by wsdl.exe.
The sample host & client projects I put together for this post are available for download below.