Hey Leute,

heute möchte ich meine Erfahrungen mit der Anbindung von externen Web Services an Dynamics NAV teilen. Dabei muss man grundsätzlich sagen, dass es zwei Formen von Web Services gibt. Zum Einen gibt es SOAP Web Services und zum Anderen gibt es REST Web Services.

Den Unterschied zwischen REST und SOAP kann man hier nachlesen: SOAP vs REST

Wenn Ihr REST Web Services konsumieren möchtet, dann kann ich nur die Serie von „Kauffmann“ empfehlen. Hier wird erklärt, wie man das macht:

NAV Techdays 2015 – The Web Service Examples

Web Services Examples Part 1 – The Basic Pattern

Web Services Examples Part 2 – Verify E-mail Address

Web Services Examples Part 3 – Generate Barcode

Web Services Example Part 4 – Send SMS text message

Web Services Example Part 5 – DocuSign Integration

Im Bereich SOAP gibt es auch ein paar Beiträge von Vjeko: Web Services Black Belt: consuming NAV web services using pure C/AL

Hier geht es allerdings um Dynamics NAV Web Services, die durch C/AL konsumiert werden. Wenn man aber nun einen fremden Web Services in Dynamics NAV konsumieren möchte, ist C/AL wohl die falsche Wahl. Zu mindestens trifft das auf mich zu. Ich möchte heute erläutern, wie man einen Web Services mit einer selbst entwickelten Klassenbibliothek konsumieren kann.

Das bedeutet ich werde heute erläutern, wie man eine Klassenbibliothek mit C# in Visual Studio 2015 erstellt, diese dann in Dynamics NAV integriert und den Web Services dann aus NAV heraus konsumiert. Wir lagern also einen kleinen Teil der Business Logik aus und haben dennoch eine Integration in Dynamics NAV.  Wer kein Visual Studio besitzt, kann evtl. die Visual Studio Community Edition nutzen Visual Studio CE. Dies ist mit gewissen Auflagen verbunden, bzw. nur bestimmte Personenkreise oder Firmen dürfen das kostenlos nutzen.

Für unser heutiges Beispiel benötigen wir also einen Web Service. Jeder öffentliche Web Services kann dafür verwendet werden. Ich verwende für das Beispiel diesen SOAP Web Service: http://www.webservicex.net/geoipservice.asmx?WSDL

Dieser Web Service gibt uns im Idealfall Informationen zu einer IP zurück. Ich werde exemplarisch zeigen, wie man von einer IP Adresse den Ländercode zurückbekommt. Dafür öffne ich zuerst Visual Studio und erstelle ein neues Projekt und eine neue Klassenbibliothek:

1.) Ist Visual Studio geöffnet über das Menüband ein neues Projekt erstellen: Datei -> Neu -> Projekt…

Web Services - 1 Neues Projekt

2.) Im Fenster „Neues Projekt“ folgendes tun: Visual C# -> Klassenbibliothek -> Name „SOAPWebServiceConnector“

Web Services - 2 Klassenbibliothek

3.) Ich benenne die Klasse von Class1 in SOAPWebServiveConnector um: Wichtig ist auch, dass die Klasse als „public“ gekennzeichnet ist. Ist dies nicht der Fall so haben wir nachher keinen Zugriff auf die Funktionen der Klasse.

Web Services - 3 C Shape Projekt

Der Vorteil von Visual Studio ist ganz klar, dass ich hier eine Web Referenz hinterlegen kann. Damit ist es mir möglich schnell und effektiv auf alle Funktionen und Klassen eines Web Services zugreifen zu können. Dafür legen wir also eine neue Web Referenz an:

1.) Rechtsklick auf Verweise und die Aktion „Dienstverweis hinzufügen“ auswählen:

2.) Im Fenster „Dienstverweis hinzufügen“ auf „Erweitert…“ klicken:

3.) In den Dienstverweiseinstellungen auf „Webverweis auswählen“ klicken:

4.) In der URL die gewünschte SOAP Web Adresse angeben. In meinem Fall ist das: „http://www.webservicex.net/geoipservice.asmx?WSDL“ und danach auf den kleinen Pfeil klicken. Nun wird die Web Service Definition importiert und gelesen. Wir hinterlegen zusätzlich einen Webverweisnamen „GeoIPWebService“ und klicken dann auch „Verweis hinzufügen“.

In unserer Klasse „SOAPWebServiceConnector“ schreiben wir nun ein paar Zeilen Programmcode. Ich lege hier eine öffentliche (von außen erreichbare) Methode GetCountryCodeByIP an.

  • Dabei bedeutet public, dass dies keine interne Funktion ist (vergleichbar mit der Eigenschaft Local in Codeunitfunktionen).
  • „string“ definiert den Datentyp des Rückgabewertes. Ich gebe also einen Text zurück!
  • „GetCountryCodeByIP“ ist der Methodenname.
  • „string IPAddress“ definiert die Parameter. In diesem Fall habe ich nur einen Parameter. Benötige ich mehrere Parameter, so trenne ich diese mit einem Komma. Möchte ich einen Paramter wieder zurück an den Aufruf der Methode geben, dann schreibe ich „ref“ vor den Datentyp.

Innerhalb der Funktion muss ich nun eine Verbindung zu dem Web Service aufbauen und den Ländercode als „return value“ zurückgeben.

  • Dafür definiere ich eine neue lokale Textvariable „CountryCode“
  • Ich rufe den Konstruktor des WebService auf. Damit stelle ich eine Verbindung her und kann mit der erstellten Variable auf die Funktionen des Web Services zugreifen. Mehr über Konstruktoren kann man hier lesen (https://msdn.microsoft.com/de-de/library/ace5hbzh.aspx)
  • Ich rufe des Weiteren den Konstruktor der Klasse „GeoIP“ auf, da dieser als Rückgabewert der Web Service Funktion erwartet wird.
  • Nun rufe ich die Funktion „GetGeoIP“ mit meinem Parameter auf. Die Klasse „GeoIP“ wird nun vom Web Service gefüllt.
  • Anschließend schreibe ich das Feld „CountryCode“ aus der Klasse „GeoIP“ in die Variable „CountryCode“ und definiere den lokalen „CountryCode“ als Rückgabewert.

Web Services - 8 Funktion zum Abruf des Web Services

Nun erstelle und veröffentliche ich meine DLL:

1.) Umstellen des Modus auf „Release“:

Web Services - 9 DLL erstellen

2.) Über das Menüband „Erstellen“ -> „SOAPWebServiceConnector neu erstellen“ auswählen.

Web Services - 10 DLL erstellen_2

3.) Den Projektordner öffnen und die kompilierten Dateien finden:

Web Services - 11 DLL erstellen_3

4.) Je nachdem ob das Addin/Klassenbibliothek Clientseitig (RunOnClient) läuft oder Serverseitig entsprechend im Server/Clientverzeichnis ablegen. In meinem Beispiel muss es im Serververzeichnis abgelegt werden. Benötigt wird lediglich die Datei „SOAPWebServiceConnector.dll“.

Web Services - 12 Addin ablegen

Web Services - 13 Addin ablegen_2

Nun ist das Addin / unsere Klassenbibliothek in Dynamics NAV verfügbar. Ich öffne den Entwicklungsclient erstelle eine neue Codeunit und integriere meine Klassenbibliothek.

Web Services - 14 Neue Codeunit

Ich erstelle hier eine Funktion „GetCountryCodeOfIPAddress und greife damit auf meinen Web Service zu. Ich übergebe eine IP-Adresse und lasse mir am Ende der Funktion per Nachricht den Ländercode zurückgeben. Auch in C/AL muss der Konstruktor einer .NET Klasse aufgerufen werden, damit wir auf die Funktionen der Klasse zugreifen können.

Web Services - 15 Codeunit Eigenschaften

Um die .NET Variable zu definieren, einfach folgende Schritte ausführen:

  • Die lokalen Variablen der Funktion öffnen
  • Als DataType „DotNet“ auswählen.
  • Beim Subtype abtauchen.
  • Unter dem Register Dynamics NAV unseren SOAPWebServiceConnector suchen.
  • Anschließend unsere Klasse „SOAPWebServiceConnector“ auswählen.
  • Mit „OK“ bestätigen.

Web Services - 16 Dotnet Variable

Zu guter letzt einfach einen Bericht erstellen, der unsere C/AL Funktion aufruft:

Web Services - 17 Execute Web Service

Web Services - 18 Execute Web Service_2

Web Services - 19 Execute Web Service_3

Ich bin kein C# oder .NET Programmierer, aber wer hätte gedacht, dass es so einfach ist einen externen SOAP Web Service zu konsumieren. Für mich ist das der leichteste Weg um einen Web Service zu konsumieren. Sicherlich gibt es hier auch noch andere Wege, aber das gibt Euch sicherlich ein paar Ideen, wie man die Anbindung verschiedener Systeme lösen kann.

Hier gibt es wie gewohnt die NAV Objekte und das Visual Studio Projekt:

160507_ConsumeSOAPWebServiceInNAV.zip

SOAPWebServiceConnector.zip