I’ve been working on building a .NET Client Application to consume a Java based Web Service hosted in an Equinox-based Server Application. I followed the standard procedure in Visual Studio to consume a Web Service
- Add Web Reference
- Instantiate Proxy Class in my client code
- Added the additional User Credential code as the Web Service requires user authentication
- Ran the App and was confronted with an HTTP Error 501 that the method i was calling is not supported
The detailed error message was Method+%3C%3FXML+is+not+defined+in+RFC+2068+ and+is+not+supported+by+the+Servlet+API+.
Using Dynatrace to instrument both my client application and the server gave me a PurePath that showed exceptions on both the server and the client side that were thrown for the single Web Service Request.
Exploring the Exception Details revealed that the problem actually happened during the resubmit of the Web Request caused by a server side authentication request (HTTP 401).
It turned out that the .NET SOAP Stack Implementation sent the HTTP Body along with the first request although the response from the server was a HTTP 401. The .NET SOAP Stack again responded with Header (now containing the authentication information) and Body (containing the XML for the Web Service call). The server side SOAP Stack implementation however was considering the HTTP Body of the first request as the response to its HTTP 401 request. Parsing this data caused the HTTP 501 error saying that <?xml … is not a supported Servlet API.
So in this particular case – the server was not expecting an HTTP Body before the authenticate was not completed. As .NET sent the HTTP body anyway it caused the server to raise an error when parsing the data.
The solution for this particular problem was to force the .NET SOAP Stack to automatically send the authentication information with the first request as its not possible to prevent sending the HTTP Body for a non authenticated HTTP Request.
I first thought that using PreAuthentication will do the trick – but it didnt. So I found a great workaround by Norman Rasmussen that solved the interoperability problem. Additionally I saved one roundtrip to the server.
We should think that SOAP has been around for a long time and that interoperability issues are problems from the past. With the insight I got into the client and server-side code it was easy to find the root cause of the problem and – with the help of others – I was able to solve it.