1

There is an external SOAP service I must interact with.

To this end I opened VisualStudio, right clicked References, clicked "Add service reference", entered the address of the WSDL document and clicked OK. This worked, VisualStudio generated for me a library - a WCF client - that can be used to interact with the said external API.

The only problem is that sometimes I was getting a System.ServiceModel.CommunicationException: Unrecognized message version.

Fiddler showed me the reason. This is the response of the server:

<h1>CException</h1>
<p>A non-numeric value encountered</p>

OK, that's definitely NOT a SOAP response, no wonder .NET refuses to parse it. But in this case can I please be able to retrieve the raw response? (perhaps it would make sense to retrieve the error from HTML tags and show it to the user)

What I tried: I read this article from the Microsoft documentation: How to: Inspect or Modify Messages on the Client It says:

To inspect or modify messages

(this is also what this SO answer suggests)

I tried both IContractBehavior and IEndpointBehavior. The result is, unfortunately, the same: the CommunicationException is thrown before my custom behaviors are called and therefore I cannot get the raw response. (If the response is a SOAP message then the exception is not thrown, my behaviors are called and I can get the raw response, but in such a case I have no interest in it :( )

Is there any way to get the raw response even if it is not a SOAP message?

  • I understand my question has one weakness: no Minimal Reproducible Example. Unfortunately, in this case I can see no way to add such a minimal reproducible example. I can't post the whole code Visual Studio generated for me, for obvious reasons. Even more importantly, the API in question is not public and it requires authorization. If there is any way I can improve my question please tell me. –  Apr 16 '21 at 04:15
  • You can implement the IDispatchMessageInspector interface to get the original response: https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.dispatcher.idispatchmessageinspector?view=netframework-4.8 – Ding Peng Apr 16 '21 at 05:08
  • @DingPeng Correct me if I'm wrong but isn't this interface expected to be implemented on the *server* rather than *client*? (I'm developing a client and have no access to server code) –  Apr 16 '21 at 05:36
  • If it is a client, you need to implement the IClientMessageInspector interface: https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.dispatcher.iclientmessageinspector?view=dotnet-plat-ext-5.0 – Ding Peng Apr 16 '21 at 05:41
  • 1
    @DingPeng Like I said in my quesiton this is what I tried doing, but to no avail. This only works if the response of the server is a correct SOAP message. If the response is not a correct SOAP message then implementing this interface does not seem to be helpful, but this is the precise situation when I need to get the raw response –  Apr 16 '21 at 05:48
  • You can try to get the original response in the Application_BeginRequest method in Global. – Ding Peng Apr 19 '21 at 01:20
  • You need to be lower in the WCF stack. Everything that uses a Message is not useful as there won't be a message. Try a custom message encoder: https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/custom-message-encoder-custom-text-encoder that gives you access to the actual bytes on the wire. You can then when you encounter that html payload build a SoapFault instaed. – rene May 11 '21 at 20:01

0 Answers0