1

I'm trying to consume a SOAP service using WCF in .NET 5. The service provider expects the content type of the request to be text/xml but sends a response with content type application/xml.

The following code throws a ProtocolException because is expects both request and response to have content type text/xml.

var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress("http://[...]/inquiry");
var channelFactory = new ChannelFactory<InquiryServiceSoapPort>(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
var inquiry = new Inquiry();
var result = serviceClient.createInquiry(inquiry);

I was able to change the content type to application/xml using a custom encoder, but that changes it for both request and response, and my request then is rejected by the server.

Is there a way to change the content type of the response only?

Edit

I am writing client-side code, not server-side code, mind you. As of now, it seems I can only catch and swallow the exception or re-implement the code either using another framework or from scratch.

thorstenmz
  • 86
  • 1
  • 4
  • "I'm trying to consume a SOAP service using WCF in .NET 5" - you have my sympathy – Dai Oct 17 '21 at 10:22
  • Out of curiosity, do you _have_ to use the (very unergonomic) old .NET WCF client code? If this is for only a handful of SOAP endpoints you could hack-it with your own logic over `HttpClient`. – Dai Oct 17 '21 at 10:27
  • You can take a look at [this case](https://stackoverflow.com/questions/6313461/change-wcf-webapi-httpcontent-response) and maybe it will help you. – Jiayao Oct 18 '21 at 11:49

1 Answers1

0

Have a look at the WCF architecture here: https://learn.microsoft.com/en-us/dotnet/framework/wcf/architecture

So we have the ABC of WCF is the Address, Binding and Contract, and here we are in the contract serialization https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-transfer-and-serialization

https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-contract-serializer

in detail: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.serialization.datacontractserializer?view=net-5.0

the are the concept i recommend diving into, the http header type "content-type" is really a function of the rest in case You make the BasicHttp binding https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.basichttpbinding?view=dotnet-plat-ext-5.0

Which is sort of only the corner of a much bigger tool available in WCF. for instance wsHttpBinding which is really preferable in many scenarios, could alone solve your problem if the endpoint is available.

In the wsHttpBinding You can control the message encoding https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/wcf/wshttpbinding

Ultimately choosing your Message encoder will determine how headers are set, there is a wealth of abstraction level(s) compared to REST io model, but it's there: https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/choosing-a-message-encoder

And You can even roll You own.

T. Nielsen
  • 835
  • 5
  • 18