DEV Community

Make SOAP requests using IHttpClientFactory in .NET Core

Bojan Nikolić on August 03, 2020

SOAP services became second class citizen in .NET Core. REST was "the-way-to-go" and who creates SOAP services these days anyways? Well, maybe not ...
Collapse
 
vekzdran profile image
Vedran Mandić

Bojan, thank you so much... this works like a charm! Excellent find and effort! :-)

Collapse
 
nikolicbojan profile image
Bojan Nikolić

No problem, really glad to hear this post helped! :)

Collapse
 
tho_shiteng_a8027f739194 profile image
Tho Shi Teng

Does this design able to cater for soap calls that require basic authentication ? i try to modify an existing soap client to enable http client factory, it always hit error :

The HTTP request is unauthorized with client authentication scheme 'Basic'.

Collapse
 
nikolicbojan profile image
Bojan Nikolić

Hi Tho,
Have you checked Caveat #2 or comment with suggestion for adding HttpHandler with Header for, in your case, basic authentication?
Basic authentication is just a Authorization header with Basic, then space, then Base64 of user:pass.

Collapse
 
nlyk profile image
nlyk

It's really helpful. Unfortunately, I have not been able to add custom HTTP Headers to the request so far. Any suggestions;

Collapse
 
nikolicbojan profile image
Bojan Nikolić

You can add them through additional DelegatingHandler which you would add to the HttpClient setup. So, create something like TraceLogHandler and append a header.
So, something like

internal class HeaderHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Add("X-MyHeader", "MyValue");

        return base.SendAsync(request, cancellationToken);
    }
}
Enter fullscreen mode Exit fullscreen mode

Then in Startup.cs first register it

services.AddScoped<HeaderHandler>();
Enter fullscreen mode Exit fullscreen mode

and then add it to the HttpClient setup e.g. before AddHeaderPropagation line

.AddHttpMessageHandler<HeaderHandler>()
Enter fullscreen mode Exit fullscreen mode

Let me know if this is not what you had in mind or it doesn't work for your case.

Collapse
 
datacruze profile image
datacruze

Hi Bojan, nice article. How would I add an X509 certificate to use the soap service with this approach? I currently use the WCF bindings to add the X509 certificate

Collapse
 
nikolicbojan profile image
Bojan Nikolić

Hi, I would suggest that you setup certificate in a constructor of a service, similarly how I setup timeouts here github.com/nikolic-bojan/soap-clie...
Maybe this example could help docs.microsoft.com/en-us/dotnet/fr...

Collapse
 
datacruze profile image
datacruze

Thanks, I added the cert but I still see TIME_WAIT when running netstat. Do you think I did not implement httpmessagehandler correctly? I documented my issue at the link below. Please let me know any suggestions
github.com/dotnet/wcf/issues/4838

Thread Thread
 
nikolicbojan profile image
Bojan Nikolić

Hi @datacruze
I would like to understand this better (checked Issue on GH) - you managed to add certificate and to call WCF service; you also conducted load tests and that was also a success; you load tested with 20 threads in parallel.
HttpMessageHandler has a default 2 minute lifetime, so all your connections should be closed after that period of time.
I checked your code on GH Issue and what I can see is that it is quite different then mine where I inject IHttpMessageHandlerFactory. I am also Closing the channel after success and Aborting on any issue or if it is not a success.
Were all of your calls a success? Could you try to close the Channel each time?

Thread Thread
 
ctechid profile image
Ey

Try to call channel.Abort(), then channel.Close(), channel.Dispose(), channel = null.