How to Create a SOAP Service in C#

Saad Aslam Feb 02, 2024
  1. Brief Explanation of SOAP
  2. SOAP Web Services
  3. Call a SOAP Service With the .NET Core in C#
  4. Use the SoapClientMessage Class in C#
  5. Create a SOAP Service With the ASP.NET Core in C#
How to Create a SOAP Service in C#

You’re not alone if you want to utilize SOAP or WCF with ASP.NET Core. It’s one of the most desired and sought-after features in .NET Core.

In this post, we’ll go through how to use a WCF SOAP service from your .NET Core application. We also demonstrate using the ASP.NET Core to establish and host a SOAP service.

Brief Explanation of SOAP

SOAP (Simple Object Access Protocol) is a protocol for transferring structured data across dispersed and perhaps diverse systems. Its communication format is XML, and it relies on application layer protocols like HTTP.

The majority of people are familiar with it as the standard protocol for online services.

SOAP was the de facto standard for building web services until recently, and the Service Oriented Architecture (SOA) was strongly reliant on it. SOAP establishes a message format that should be followed, but we are free to include whatever we want inside it - binary attachments are even available.

The SOAP standard provides a contained envelope (envelope >), which can include a header (header >) and a body (body >), the latter of which can contain a fault section (fault >) as well as other subsections. Only body > is required, and fault > is reserved for answers, not requests, in which an error has occurred.

The ability to incorporate portions of binary material during a message is called Message Transmission Optimization Mechanism (MTOM), and it’s an alternative to utilizing Base-64 to encode binary streams, making them 30 percent bigger.

SOAP Web Services

When calling online services, the body must include the action to be performed and any arguments that may be provided. POST is always used by SOAP web services, and the envelope is always sent as the payload to a single well-known URL.

The web service framework will route the request to a specific system class and function.

Web service makes a Web Services Definition Language (WSDL) file available that contains information about the service, such as the name of each action method, the arguments and return values for each, and the expected errors. Visual Studio (and other tools like the SVCUtil.exe command-line program) can produce code proxies that interface with the web service using this WSDL.

Call a SOAP Service With the .NET Core in C#

As a result, if you wish to utilize WCF on the client-side with .NET Core, you can. First, double-check that you’ve included the System.ServiceModel.

One of the System’s primitives ServiceModel.Http or System (for BasicHttpBinding/BasicHttpsBinding or NetHttpBinding/NetHttpsBinding bindings, which encompass SOAP and REST). ServiceModel.NetTcp is a protocol that allows you to send and receive (for NetTcpBinding, a Windows-only binary protocol).

Let’s look at a basic example.

First, the contract:

public interface IPServ {
  string P(string msg);
}

Then the client code:

var bind = new BasicHttpBinding();
var endp = new EndpointAddress(new Uri("[url]"));
var cF = new ChannelFactory(bind, endp);
var servC = cF.CreateChannel();
var res = servC.Ping("Ping");
cF.Close();

Everything is the same as it would be if you were working in the complete .NET framework, as you can see. Since there are no App.config or Web.config files, you will need to manually configure everything, such as creating the correct binding and endpoint address.

You may also manually generate .NET Core-compatible proxy classes using the svcutil.exe program. This will allow you to use .NET Core.

It’s easy to overlook how difficult it may be to configure ASP.NET Core with SOAP when you consider how easy it is.

Use the SoapClientMessage Class in C#

The SOAP extension that records the SOAP messages delivered and received by an XML web service client includes the following code segment. The SoapClientMessage sent into the SoapExtension is processed by this fragment.

The SOAP extension’s ProcessMessage function writes the SoapClientMessage properties to the log file.

// Process the SOAP message received and write it to a log file.
public override void PM(SoapMessage m) {
  switch (m.Stage) {
    case SoapMessageStage.BeforeSerialize:
      break;
    case SoapMessageStage.AfterSerialize:
      WriteOutput((SoapClientMessage)m);
      break;
    case SoapMessageStage.BeforeDeserialize:
      WriteInput((SoapClientMessage)m);
      break;
    case SoapMessageStage.AfterDeserialize:
      break;
    default:
      throw new Exception("this is and invalid state");
  }
}

To output, the log of the outgoing SOAP message to the file is called the log file.

public void WO(SoapClientMessage m) {
  newStream.Position = 0;
  FileStream mf = new FileStream(filename, FileMode.Append, FileAccess.Write);
  StreamWriter ms = new StreamWriter(mf);
  ms.WriteLine("--> Requested at " + DateTime.Now);

  // Print to the log file the  field of request header for header SoapAction .
  ms.WriteLine("The  Http SoapAction  header request field is: ");
  ms.WriteLine("\t" + m.Action);

  // Write the client type that called the XML Web service method to the log file.
  ms.WriteLine("The client type is: ");
  if ((m.Client.GetType()).Equals(typeof(MathSvc)))
    ms.WriteLine("\tMathSvc");

  // The client's technique will be printed to the log file.
  ms.WriteLine("The approach that the client has requested is:");
  ms.WriteLine("\t" + m.MethodInfo.Name);

  // The client's technique will be printed on the log file.
  if (m.OneWay)
    ms.WriteLine("The client does not wait for the server to complete the task.");
  else
    ms.WriteLine("The client waits for the server to complete the task.");

  // The URL of the site that implements the method is printed to the log file.
  ms.WriteLine("The XML Web service method that has been requested has the following URL: ");
  ms.WriteLine("\t" + m.Url);
  ms.WriteLine("The SOAP envelope's contents are as follows: ");
  ms.Flush();

  // Copy one stream's content to another.
  Copy(newStream, mf);
  mf.Close();
  newStream.Position = 0;

  // Copy one stream's content to another.
  Copy(newStream, oldStream);
}

Create a SOAP Service With the ASP.NET Core in C#

For the client-side, for example, you may use the same class that we showed before. You’ll need to develop a service class that implements the contract on the server-side:

public class SS : IPServ {
  public string P(string m) {
    return string.Join(string.Empty, m.Reverse());
  }
}

And all we have to do now is register the service implementation at the following address:

public void ConfigServ(IServColl s) {
  s.AddSingleton(new PingService());
  s.AddMvc();
  // rest code goes here
}
public void Conf(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
  app.UseSoapEndpoint(path: "/PingService.svc", binding: new BasicHttpBinding());
  app.UseMvc();
  // rest code goes here
}

You may implement a custom exception-to-string transformer to extract a meaningful message from any exception that should occur and provide it to the client as a fault string if you want to:

s.AddSoapExceptionTransformer((ex) = > ex.Message);

The code injects a custom middleware into the ASP.NET Core pipeline that listens for HTTP POSTs and checks for valid headers. It extracts the action method and parameters from the payload before forwarding it to the specified implementation class.

A Handful of Points to Consider

  1. The .svc extension isn’t required; it’s merely there to remind us that WCF formerly required it.
  2. For PingService, you may utilize any life cycle, not just singletons.
  3. The client and server bindings must be the same.
  4. You won’t be able to utilize any of the ASP.NET Core filters since they’ll be ignored, but you may use dependency injection instead.

Even though you may certainly use this code for backward compatibility, be aware of the following constraints if you need to write a SOAP service in .NET Core (for example, if you need to deploy it to Docker):

  1. The WS - *standards are not supported.
  2. There is no support for MTOM.
  3. Other than HTTPS and the built-in security of ASP.NET Core, there is no support for security.
  4. There will be no throttling or inappropriate behavior.
Author: Saad Aslam
Saad Aslam avatar Saad Aslam avatar

I'm a Flutter application developer with 1 year of professional experience in the field. I've created applications for both, android and iOS using AWS and Firebase, as the backend. I've written articles relating to the theoretical and problem-solving aspects of C, C++, and C#. I'm currently enrolled in an undergraduate program for Information Technology.

LinkedIn