Access XML SOAP services in .NET Core and client certificates (SSL)

WCF meets .NET Core

Only a few years back Windows Communication Foundation (WCF) was the way to do communication on the Microsoft platform based on SOAP protocol. Now a days new services are mostly build on top of Representational State Transfer (REST) Services. Sometimes you have to access a ‘legacy’ SOAP services for .NET Core. .NET Core has limited WCF support. In this blog post I’ll explain how to consume SOAP services form .NET Core.

Connect to SOAP Service from .NET Core
When using .NET Core there is basic support for SOAP Services. Most business to business SOAP Services use XML over HTTP. Fortunately these services are easy to access from .NET Core. Feature like more advanced bindings Named pipes or MSMQ are not supported. Configuration was very easy to do from configuration files (app.config/web.config), this have to be done in code.

The following steps can be followed to create a client for a HelloWorld service client:

  • Add NuGet packages System.ServiceModel.Http and System.ServiceModel.Primitives to your project
  • Create proxy classes by hand or use svcutil.exe to generate proxy classes for the service
  • Build your binding, endpoint and channel
  • Invoke the service

The first step is to add the references System.ServiceModel.Http and System.ServiceModel.Primitives to your project. These references contain the classes to setup a connection to the server.

Now you are ready to create proxy classes which can be used to setup the connection. You can create them by hand or use the svcutil.exe tool. The svcutil.exe tool can use the WSDL of the webservice. A by hand created service contract for a HelloWorld service can look like:

[ServiceContract]
public interface IHelloWorld
{
    [OperationContract]
    string HellowWorld(string name);
}

The code for setting up the connection and invoking the service:

var binding = new BasicHttpBinding();
var endpoint = new EndpointAddress(new Uri(serviceUrl));
ChannelFactory factory = new ChannelFactory(binding, endpoint);
IHelloWorld channel = factory.CreateChannel();
var responseMessage = channel.HelloWorld("name");

Now you are ready to invoke the service and see if it all works.

Load Certificates on Linux or Containers .NET Core
When a service uses X.509 certificates to do authentication you need to add the certificate to your channel.
8f7b8968-899f-4538-a9e8-0eaa872a291c

When running on windows you are able to use the Certificate Store to manage your certificates and load then directly from there. On Linux you do have to load the certificates by hand. The following code shows how to assign a certificate to your channel:

var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var endpoint = new EndpointAddress(new Uri(serviceUrl));
ChannelFactory factory = new ChannelFactory(binding, endpoint);
var certificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatepath));
factory.Credentials.ClientCertificate.Certificate = certificate;
IHelloWorld channel = factory.CreateChannel();
var responseMessage = channel.HelloWorld("name");

Final thought

Building a client for basic SOAP services using .NET Core is easy. When communicating with XML SOAP messages over SSL works all out of the box. However when you need to do more complicated things like MTOM (Binary), throttling, ws-* specifications or advanced security will not work.

Advertisement

One thought on “Access XML SOAP services in .NET Core and client certificates (SSL)”

  1. I am using a .NET Core Web API which talks to a service hosted on the same server, so I wanted to use the named pipe binding, but .NET Core won’t support that in the generated client code so I just went with the HTTP binding and only used a localhost domain. I say this because it took me a while to figure out why a .NET Core project couldn’t generate code from another project in the solution that has a named pipe URL. I hope that can help others.

    TL;DR

    I which I did not have to use WCF or .NET Framework in any way, however I have to use an antiquated assembly style API from a third party provider who hasn’t really kept up with the times. I have been using my own RESTful API in .NET Framework, but all of my other APIs use .NET Core which also use my hybrid Oauth2.0 security libraries. Also, the third party API isn’t optimized for a RESTful approach as it can be very slow and therefore can make the wrapper API’s calls very slow.

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: