I’m coding an ASP.NET MVC 3 web site in Visual Studio 2010. I added a service reference to a SOAP 1.2 version of a web service and started updating my code (I was using a SOAP 1.1 endpoint previously).
Unfortunately the switchover wasn’t as clean as I had hoped. The first method I changed resulted in an error, even on a call that appeared identical to the previous version. The error message I received was:
The CustomBinding on the ServiceEndpoint with contract 'SubscriberServices' lacks a TransportBindingElement. Every binding must have at least one binding element that derives from TransportBindingElement.
…which looked like this:
For the quick fix, head to the end of this article. Keep reading if you want to know what’s going on.
What Was Going On?
The two things that gave me the strongest clues where “CustomBinding” and “TransportBindingElement”, but for different reasons. CustomBinding was a little unexpected as the service was added via HTTP. I guess I always assumed that it would be using an HTTP binding? The other piece suggested a derivative of the TransportBindingElement, which according to MSDN is an abstract base class.
Off to Our Config File
Actually, at this point, I wanted less noise, so I quickly created a console app and added references to both services. The differences were, at this point, fairly obvious. The 1.1 version of the service was using a basicHttpBinding element (which I was expecting), whereas the 1.2 service was using a custom binding:
So, what we’re looking at is trying to get the custom binding to know which transport we want to use. This is something that is implicit in the basicHttpBinding but needs to be explicitly set for customBindings.
Following the links on the TransportBindingElement will lead us to the httpTransportbindingElement, which has both code and config file samples. Adding a short and simple section to the binding did the trick; all I needed was an httpTransport element in the customBinding\binding element. The updated config section looked like this with the MSDN sample config injected:
Further reading shows that all the properties set in the MSDN example are actually all defaults, which means that our httpTransport element can simply be reduced to a single, self-closing tag:
So, in short, if you’re using a SOAP 1.2 service reference, or any service reference that requires the use of a custom binding, make sure you’ve added a TransportBindingElement (such as httpTransport) to your config file or in your code.