Erstellen einen SOAP-Dienst in C#

Saad Aslam 12 Oktober 2023
  1. Kurze Erläuterung von SOAP
  2. SOAP-Webdienste
  3. Aufrufen eines SOAP-Dienstes mit .NET Core in C#
  4. Verwendung von die Klasse SoapClientMessage in C#
  5. Erstellen Sie einen SOAP-Dienst mit ASP.NET Core in C#
Erstellen einen SOAP-Dienst in C#

Sie sind nicht allein, wenn Sie SOAP oder WCF mit ASP.NET Core verwenden möchten. Es ist eines der begehrtesten und gefragtesten Features in .NET Core.

In diesem Beitrag wird erläutert, wie Sie einen WCF-SOAP-Dienst aus Ihrer .NET Core-Anwendung verwenden. Wir demonstrieren auch die Verwendung von ASP.NET Core zum Einrichten und Hosten eines SOAP-Diensts.

Kurze Erläuterung von SOAP

SOAP (Simple Object Access Protocol) ist ein Protokoll zur Übertragung strukturierter Daten über verteilte und möglicherweise unterschiedliche Systeme. Sein Kommunikationsformat ist XML und es stützt sich auf Protokolle der Anwendungsschicht wie HTTP.

Die Mehrheit kennt es als Standardprotokoll für Online-Dienste.

SOAP war bis vor kurzem der De-facto-Standard zum Erstellen von Webdiensten, und die serviceorientierte Architektur (SOA) war stark davon abhängig. SOAP legt ein Nachrichtenformat fest, das befolgt werden sollte, aber es steht uns frei, darin alles einzufügen, was wir wollen – binäre Anhänge sind sogar verfügbar.

Der SOAP-Standard stellt einen enthaltenen Umschlag (envelope >) bereit, der einen Header (header >) und einen Body (body >) enthalten kann, wobei letzterer einen Fehlerabschnitt (fault >) enthalten kann. sowie weitere Unterabschnitte. Nur body > ist erforderlich, und fault > ist für Antworten reserviert, nicht für Anfragen, bei denen ein Fehler aufgetreten ist.

Die Fähigkeit, Teile von Binärmaterial in eine Nachricht einzufügen, wird als Message Transmission Optimization Mechanism (MTOM) bezeichnet und ist eine Alternative zur Verwendung von Base-64 zur Codierung von Binärströmen, wodurch sie um 30 Prozent größer werden.

SOAP-Webdienste

Beim Aufruf von Online-Diensten muss die Stelle die auszuführende Aktion und eventuelle Argumente enthalten. POST wird immer von SOAP-Webdiensten verwendet, und der Umschlag wird immer als Nutzlast an eine einzige bekannte URL gesendet.

Das Webdienst-Framework leitet die Anforderung an eine bestimmte Systemklasse und -funktion weiter.

Der Webdienst stellt eine WSDL-Datei (Web Services Definition Language) zur Verfügung, die Informationen über den Dienst enthält, z. B. den Namen jeder Aktionsmethode, die Argumente und Rückgabewerte für jede sowie die erwarteten Fehler. Visual Studio (und andere Tools wie das Befehlszeilenprogramm SVCUtil.exe) können Codeproxys erstellen, die mit dieser WSDL eine Schnittstelle zum Webdienst bilden.

Aufrufen eines SOAP-Dienstes mit .NET Core in C#

Wenn Sie also WCF auf der Clientseite mit .NET Core verwenden möchten, können Sie dies tun. Überprüfen Sie zunächst, ob Sie das System.ServiceModel eingebunden haben.

Eines der Grundelemente des Systems ServiceModel.Http oder System (für BasicHttpBinding/BasicHttpsBinding- oder NetHttpBinding/NetHttpsBinding-Bindungen, die SOAP und REST umfassen). ServiceModel.NetTcp ist ein Protokoll, mit dem Sie senden und empfangen können (für NetTcpBinding, ein reines Windows-Binärprotokoll).

Schauen wir uns ein einfaches Beispiel an.

Zuerst der Vertrag:

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

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

Wie Sie sehen, ist alles so, als würden Sie im vollständigen .NET-Framework arbeiten. Da es keine App.config- oder Web.config-Dateien gibt, müssen Sie alles manuell konfigurieren, wie z. B. das Erstellen der richtigen Bindung und Endpunktadresse.

Sie können .NET Core-kompatible Proxy-Klassen auch manuell mit dem Programm svcutil.exe generieren. Dadurch können Sie .NET Core verwenden.

Es ist leicht zu übersehen, wie schwierig es sein kann, ASP.NET Core mit SOAP zu konfigurieren, wenn man bedenkt, wie einfach es ist.

Verwendung von die Klasse SoapClientMessage in C#

Die SOAP-Erweiterung, die die von einem XML-Webdienstclient gelieferten und empfangenen SOAP-Nachrichten aufzeichnet, enthält das folgende Codesegment. Die in die SoapExtension gesendete SoapClientMessage wird von diesem Fragment verarbeitet.

Die Funktion ProcessMessage der SOAP-Erweiterung schreibt die SoapClientMessage-Eigenschaften in die Protokolldatei.

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

Für die Ausgabe wird das Protokoll der ausgehenden SOAP-Nachricht an die Datei als Protokolldatei bezeichnet.

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

Erstellen Sie einen SOAP-Dienst mit ASP.NET Core in C#

Für die Client-Seite können Sie beispielsweise dieselbe Klasse verwenden, die wir zuvor gezeigt haben. Sie müssen eine Dienstklasse entwickeln, die den Vertrag auf der Serverseite implementiert:

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

Und jetzt müssen wir nur noch die Service-Implementierung unter folgender Adresse registrieren:

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
}

Sie können einen benutzerdefinierten Ausnahme-zu-String-Transformer implementieren, um eine aussagekräftige Nachricht aus jeder auftretenden Ausnahme zu extrahieren und sie dem Client als Fehlerzeichenfolge bereitzustellen, wenn Sie Folgendes möchten:

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

Der Code fügt eine benutzerdefinierte Middleware in die ASP.NET Core-Pipeline ein, die auf HTTP POSTs lauscht und auf gültige Header prüft. Es extrahiert die Aktionsmethode und Parameter aus der Nutzlast, bevor es sie an die angegebene Implementierungsklasse weiterleitet.

Eine Handvoll zu berücksichtigender Punkte

  1. Die Erweiterung .svc ist nicht erforderlich; es ist nur dazu da, uns daran zu erinnern, dass WCF es früher verlangt hat.
  2. Für PingService können Sie jeden Lebenszyklus verwenden, nicht nur Singletons.
  3. Die Client- und Serverbindungen müssen identisch sein.
  4. Sie können keinen der ASP.NET Core-Filter verwenden, da sie ignoriert werden, aber Sie können stattdessen die Abhängigkeitsinjektion verwenden.

Auch wenn Sie diesen Code sicherlich aus Gründen der Abwärtskompatibilität verwenden können, beachten Sie die folgenden Einschränkungen, wenn Sie einen SOAP-Dienst in .NET Core schreiben müssen (z. B. wenn Sie ihn in Docker bereitstellen müssen):

  1. Die WS - *Standards werden nicht unterstützt.
  2. MTOM wird nicht unterstützt.
  3. Abgesehen von HTTPS und der integrierten Sicherheit von ASP.NET Core gibt es keine Unterstützung für Sicherheit.
  4. Es wird kein Drosseln oder unangemessenes Verhalten geben.
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