Crear un servicio SOAP en C#

Saad Aslam 12 octubre 2023
  1. Breve explicación de SOAP
  2. Servicios web SOAP
  3. Llame a un servicio SOAP con .NET Core en C#
  4. Utilice la clase SoapClientMessage en C#
  5. Cree un servicio SOAP con ASP.NET Core en C#
Crear un servicio SOAP en C#

No está solo si desea utilizar SOAP o WCF con ASP.NET Core. Es una de las características más deseadas y buscadas en .NET Core.

En esta publicación, veremos cómo usar un servicio WCF SOAP desde su aplicación .NET Core. También demostramos el uso de ASP.NET Core para establecer y hospedar un servicio SOAP.

Breve explicación de SOAP

SOAP (Protocolo simple de acceso a objetos) es un protocolo para transferir datos estructurados a través de sistemas dispersos y quizás diversos. Su formato de comunicación es XML y se basa en protocolos de capa de aplicación como HTTP.

La mayoría de las personas lo conocen como el protocolo estándar para los servicios en línea.

SOAP era el estándar de facto para crear servicios web hasta hace poco, y la arquitectura orientada a servicios (SOA) dependía en gran medida de él. SOAP establece un formato de mensaje que debe seguirse, pero somos libres de incluir lo que queramos dentro de él; incluso hay archivos adjuntos binarios disponibles.

El estándar SOAP proporciona un sobre contenido (envelope >), que puede incluir un encabezado (header >) y un cuerpo (body >), el último de los cuales puede contener una sección de error (fault >) así como otras subsecciones. Sólo se requiere cuerpo > y se reserva fault > para las respuestas, no para las solicitudes, en las que se ha producido un error.

La capacidad de incorporar porciones de material binario durante un mensaje se llama Mecanismo de optimización de transmisión de mensajes (MTOM), y es una alternativa a utilizar Base-64 para codificar transmisiones binarias, haciéndolas un 30 por ciento más grandes.

Servicios web SOAP

Al llamar a los servicios en línea, el cuerpo debe incluir la acción a realizar y los argumentos que se pueden proporcionar. Los servicios web SOAP siempre utilizan POST y el sobre siempre se envía como carga útil a una sola URL conocida.

El marco del servicio web enrutará la solicitud a una clase y función de sistema específicas.

El servicio web pone a disposición un archivo de lenguaje de definición de servicios web (WSDL) que contiene información sobre el servicio, como el nombre de cada método de acción, los argumentos y los valores devueltos para cada uno, y los errores esperados. Visual Studio (y otras herramientas como el programa de línea de comandos SVCUtil.exe) pueden producir proxies de código que interactúan con el servicio web mediante este WSDL.

Llame a un servicio SOAP con .NET Core en C#

Como resultado, si desea utilizar WCF en el lado del cliente con .NET Core, puede hacerlo. Primero, verifique que haya incluido el System.ServiceModel.

Una de las primitivas del sistema ServiceModel.Http o System (para enlaces BasicHttpBinding/BasicHttpsBinding o NetHttpBinding/NetHttpsBinding, que abarcan SOAP y REST). ServiceModel.NetTcp es un protocolo que le permite enviar y recibir (para NetTcpBinding, un protocolo binario exclusivo de Windows).

Veamos un ejemplo básico.

Primero, el contrato:

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

Luego el código del cliente:

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();

Todo es igual que si estuviera trabajando en el marco completo de .NET, como puede ver. Dado que no hay archivos App.config o Web.config, deberá configurar todo manualmente, como crear el enlace correcto y la dirección del punto final.

También puede generar manualmente clases de proxy compatibles con .NET Core utilizando el programa svcutil.exe. Esto le permitirá usar .NET Core.

Es fácil pasar por alto lo difícil que puede ser configurar ASP.NET Core con SOAP cuando considera lo fácil que es.

Utilice la clase SoapClientMessage en C#

La extensión SOAP que registra los mensajes SOAP entregados y recibidos por un cliente de servicio web XML incluye el siguiente segmento de código. Este fragmento procesa el SoapClientMessage enviado a SoapExtension.

La función ProcessMessage de la extensión SOAP escribe las propiedades SoapClientMessage en el archivo de registro.

// 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");
  }
}

Para la salida, el registro del mensaje SOAP saliente al archivo se denomina archivo de registro.

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);
}

Cree un servicio SOAP con ASP.NET Core en C#

Para el lado del cliente, por ejemplo, puede usar la misma clase que mostramos antes. Deberá desarrollar una clase de servicio que implemente el contrato en el lado del servidor:

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

Y todo lo que tenemos que hacer ahora es registrar la implementación del servicio en la siguiente dirección:

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
}

Puede implementar un transformador personalizado de excepción a cadena para extraer un mensaje significativo de cualquier excepción que deba ocurrir y proporcionarlo al cliente como una cadena de error si desea:

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

El código inyecta un middleware personalizado en la canalización de ASP.NET Core que escucha HTTP POST y busca encabezados válidos. Extrae el método de acción y los parámetros de la carga útil antes de reenviarlo a la clase de implementación especificada.

Un puñado de puntos a considerar

  1. No se requiere la extensión .svc; simplemente está ahí para recordarnos que WCF lo requería anteriormente.
  2. Para PingService, puede utilizar cualquier ciclo de vida, no solo singletons.
  3. Los enlaces de cliente y servidor deben ser los mismos.
  4. No podrá utilizar ninguno de los filtros de ASP.NET Core, ya que se ignorarán, pero puede usar la inyección de dependencia en su lugar.

Aunque ciertamente puede usar este código para la compatibilidad con versiones anteriores, tenga en cuenta las siguientes restricciones si necesita escribir un servicio SOAP en .NET Core (por ejemplo, si necesita implementarlo en Docker):

  1. No se admiten los estándares WS - *.
  2. No hay soporte para MTOM.
  3. Aparte de HTTPS y la seguridad integrada de ASP.NET Core, no hay soporte para la seguridad.
  4. No habrá estrangulamiento o comportamiento inapropiado.
Autor: 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