Webservice mit C# am Beispiel von DHL-Etiketten

Wenn Sie ein Abonnement des Magazins 'DATENBANKENTWICKLER' besitzen, können Sie sich anmelden und den kompletten Artikel lesen.
Anderenfalls können Sie das Abonnement hier im Shop erwerben.

Webservice mit C# am Beispiel von DHL-Etiketten

Mit Webservices lässt sich der Abruf von Daten bestimmter Anbieter aus dem Internet stark vereinfachen. Während Sie etwa zum Herunterladen eines Versandetiketts einige Minuten investieren müssen, um die Adressen und weitere Sendungsdaten aus einer Kundendatenbank in ein Onlineformular zu übertragen, könnten Sie das auch per Mausklick erledigen. Voraussetzung sind einige Zeilen Code und die Registrierung beim entsprechenden Webservice. In diesem Fall schauen wir uns das am Beispiel von Versandetiketten des Paketdienstleisters DHL an.

Im Artikel Webservice testen am Beispiel von DHL haben wir uns bereits angesehen, wie Sie die für einen Webservice wichtige WSDL-Datei ermitteln und damit über ein Tool wie SoapUI die XML-Vorlage für einen Request ermitteln, füllen und testen. Dort haben wir außerdem ein Entwickler-Konto angelegt, mit dem wir auf den Webservice von DHL zugreifen können. Schließlich haben wir einen funktionierenden Aufruf an die Sandbox-Version des Webservice, also eine zu Testzwecken bestimmte Umgebung, abgesetzt und mit dem zurückgelieferten Link ein PDF-Dokument mit dem Versandetikett erhalten (siehe Bild 1).

Aufruf des Dienstes Intraship

Bild 1: Aufruf des Dienstes Intraship

Nun wollen wir uns die Techniken ansehen, die dafür nötig sind, einen Request an einen Webservice abzusenden und die Antwort auszuwerten. Hier interessiert uns im vorliegenden Beispiel natürlich vor allem, wie wir den Link zum PDF-Dokument mit dem Versandetikett verarbeiten und das PDF-Dokument auf der Festplatte speichern oder ausdrucken.

Anfrage zusammenstellen und abschicken

Wir wollen zunächst den XML-Request, den wir im Artikel Webservice testen am Beispiel von DHL ermittelt haben, an den Webservice schicken und den Request entgegennehmen. Dabei müssen wir natürlich auch noch die Authentifizierung berücksichtigen. Um die Funktion zum Ermitteln des Response-Dokuments aufzurufen, verwenden wir ein Fenster in einer WPF-Anwendung, das wir mit einer entsprechenden Schaltfläche ausstatten.

Diese gibt dann einfach den Code in einem Meldungsfenster aus (siehe Listing 1).

private void btnEinfacherAufruf_Click(object sender, RoutedEventArgs e) {
     MessageBox.Show(GetResponse());
}

Listing 1: Aufruf der Funktion zum Senden eines Requests an den Webservice

Um die verschiedenen nachfolgend verwendeten Klassen zu nutzen, die sich auf den Umgang mit dem Webservice, XML-Dokumenten und das Lesen und Schreiben von Dokumenten beschäftigen, benötigen wir noch drei Namespaces, die wir mit dem using-Schlüsselwort einbinden:

using System.Net;
using System.Xml;
using System.IO;

Die Funktion GetResponse, die den Ablauf steuert, finden sieht wie folgt aus:

public string GetResponse() {
     HttpWebRequest request = CreateRequest();
     XmlDocument requestXML = GetRequestXML();
     using (Stream stream = request.GetRequestStream()) {
         requestXML.Save(stream);
     }
     using (WebResponse response = request.GetResponse()) {
         using (StreamReader rd = new StreamReader(response.GetResponseStream())) {
             var result = rd.ReadToEnd();
             return result;
         }
     }
}

Hier ermitteln wir mit der Funktion CreateRequest ein neues Objekt des Typs HttpWebRequest und speichern es in der Variablen request. Dabei werden Informationen wie die Header für den Aufruf, die Authentifikation und weitere Informationen in einem Objekt zusammenstellt – mehr dazu weiter unten. Danach füllen wir ein Objekt des Typs XmlDocument namens requestXML, und zwar ebenfalls mithilfe einer Funktion. Diese heißt GetRequestXML und stellt einfach nur das XML-Dokument zusammen, das als Inhalt des Requests verwendet werden soll. Wir haben also nun ein Objekt des Typs HttpWebRequest, welches die Daten für die Steuerung des Requests enthält, und ein XML-Dokument mit dem zu übergebenen Request.

Nun müssen wir beide noch verheiraten. Dies geschieht im ersten using-Konstrukt der Funktion GetResponse. Das in Klammern hinter der using-Anweisung erzeugte Objekt wird nach dem Durchlaufen des using-Abschnitts wieder gelöscht. In diesem Fall handelt es sich um ein Stream-Objekt. Diesem weisen wir das mit der Funktion GetRequestStream ermittelte Stream-Objekt unseres HttpWebRequest namens request zu. Wir haben also mit stream ein Stream-Objekt referenziert, dass wir nun füllen können und so den übergebenen Inhalt als Request-Inhalt an das HttpWebRequest-Objekt übergeben. Dies erledigen wir mit der einzigen Anweisung des using-Konstrukts, mit der wir das in requestXML gespeicherte XML-Objekt in den Stream und somit in das Objekt request speichern.

Das zweite using-Konstrukt ruft dann bereits die Methode GetResponse von request auf und speichert das Ergebnis in der Variablen response mit dem Datentyp WebResponse. resonse liefert mit GetResponseStream wiederum einen Stream, den wir diesmal allerdings nicht in einem Stream-Objekt speichern, sondern einem StreamReader als Konstruktorparameter übergeben. Wir erstellen also ein neues StreamReader-Objekt und weisen diesem den Stream zu, den wir als Antwort des Webservice erhalten haben. Diesen in rd gespeicherten Streamreader kapseln wir wiederum in einem using-Konstrukt, da wir ihn nur für die folgenden beiden Anweisungen benötigen. Die erste liest mit ReadToEnd den kompletten Inhalt des in rd gespeicherten Streams und fügt ihn der Variablen result hinzu. result, dass zu diesem Zeitpunkt das XML-Dokument mit der Antwort des Webservices enthält, wird dann schließlich als Funktionswert zurückgegeben. Die aufrufende Methode gibt den Inhalt dann schließlich wie in Bild 2 als Meldung aus.

Ergebnis des Requests

Bild 2: Ergebnis des Requests

Request zusammenstellen

Die Funktion CreateRequest stellt den Request zusammen und gibt diesen als HttpWebRequest-Objekt an die aufrufende Instanz zurück. Dabei legt diese zunächst ein Uri-Objekt an und hinterlegt die Uri, die als Endpunkt für den Webservice dient (hier der Request für die Sandbox: https://cig.dhl.de/services/sandbox/soap). Danach erstellt sie das HttpWeb­Request-Objekt auf Basis der Methode Create der Klasse WebRequest. Dieser übergibt sie das Uri-Objekt mit dem Endpunkt als Parameter. Das Ergebnis wird schließlich in den Typ HttpWebRequest umgewandelt. Danach stellt die Funktion die Zeichenkette für die Authentifizierung zusammen. Der Benutzername und das Kennwort werden zunächst in die Variablen username und password geschrieben (später fragen Sie die Daten entweder ab oder speichern direkt die kodierte Form), durch einen Doppelpunkt voneinander getrennt in einer neuen Zeichenkette aufgenommen und in einen Base64-String umgewandelt. Das Ergebnis landet in der Variablen auth. Danach fügt die Add-Methode der Headers-Auflistung des in request gespeicherten WebHttpRequest-Objekts einen neuen Header mit dem Namen Authorization und dem aus der Zeichenkette Basic, einem Leerzeichen und der kodierten Version aus Benutzername und Kennwort als Wert hinzu. Danach legt sie noch die Eigenschaften ContentType (text/xml;charset="utf-8"), Accept (text/xml) und Method (POST) von request fest. Danach gibt die Methode den Inhalt der Objektvariablen request an die aufrufende Methode zurück:

public HttpWebRequest CreateRequest() {
     Uri uri = new Uri("https://cig.dhl.de/services/sandbox/soap");
     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@uri);
     String username = "andreminhorst";
     String password = "*********";
     String auth = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
     request.Headers.Add("Authorization", "Basic " + auth);
     request.ContentType = "text/xml;charset="utf-8"";
     request.Accept = "text/xml";
     request.Method = "POST";
     return request;
}

XML-Dokument zusammenstellen

Damit kommen wir zur letzten Funktionsmethode, die wir für den ersten Aufruf benötigen. Diese heißt GetRequestXML und erstellt zunächst ein neues Objekt des Typs XmlDocument. Die Variable für dieses Objekt heißt requestXML.

Es soll nun mit dem als Zeichenkette vorhandenen XML-Dokument gefüllt werden, welches wir im Artikel Webservice testen am Beispiel von DHL zusammengestellt und ausprobiert haben. Diese Zeichenkette laden wir mit der Methode LoadXml in das Objekt requestXML und geben dieses als Rückgabewert an die aufrufende Methode zurück:

public XmlDocument GetRequestXML() {
     XmlDocument requestXML = new XmlDocument();
     requestXML.LoadXml(@"<soapenv:Envelope ...>
         <soapenv:Header>
	        <cis:Authentification>
	        <cis:user>2222222222_01</cis:user>
                 <cis:signature>pass</cis:signature>
             </cis:Authentification>
         </soapenv:Header>
         ---
     </soapenv:Envelope>");
     return requestXML;
}

Damit haben wir mit nicht allzu vielen Zeilen einen funktionierenden Aufruf eines Webservice erstellt, der in seinem Response zum Beispiel den Link zu einer PDF-Datei mit dem gewünschten Versandetikett zurückliefert.

Nächste Schritte

Dies war die Leseprobe dieses Artikels.
Melden Sie sich an, um auf den vollständigen Artikel zuzugreifen.

Bitte geben Sie die Zeichenfolge in das nachfolgende Textfeld ein

Die mit einem * markierten Felder sind Pflichtfelder.

Ich habe die Datenschutzbestimmungen zur Kenntnis genommen.