ASP.net Web Api 2-Webservice durch SSIS-Paket aufrufen (Teil 2: Test-Client erstellen)
avatar

Das Problem

Ausgehend vom Artikel 1 dieser Serie wird in diesem Artikel ein Testclient für den Webservice als Konsolen-Anwendung erstellt.
Das Ziel ist es, später einen SSIS-Skript-Task für diese Aufgabe zu erstellen.

Die Lösung

Zunächst wird eine neue C#-Konsolen-Anwendung erstellt.
Dieser Anwendung wird dann eine Klasse „Product“ hinzugefügt, durch welche später das deserialisierte Objekt aus der JSON-Rückgabe des Webservice erstellt wird.

Die Klasse ist zu der Klasse „Product“ aus dem ersten Teil dieser Serie identisch. Der Vollständigkeit halber hier nochmal der zugehörige Code:

  1. namespace TestWebApi2.Models
  2. {
  3.   public class Product
  4.   {
  5.     public string Id { get; set; }
  6.     public string Name { get; set; }
  7.     public string Category { get; set; }
  8.     public decimal Price { get; set; }
  9.   }
  10. }

Anschließend wird die eigentliche Logik in der „Program.cs“ implementiert (da es sich hierbei nur um einen kleinen POC handelt, habe ich auf eine weitgehende Strukturierung in mehrere Dateien verzichtet):

  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Net;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using System.Web.Script.Serialization;
  9. namespace TestClient
  10. {
  11.   class Program
  12.   {
  13.      public static void Main(string[] args)
  14.      {
  15.     GetData(„1,2,3“);
  16.      }
  17.    private static void GetData(string ids)
  18.    {
  19.    string webSrvUrl = „http://localhost:62706/api/Products/GetProducts“;
  20.    string postData = string.Format(„[{0}]“, ids);
  21.    var result = GetWebServiceResult(webSrvUrl, postData);
  22.   foreach (var row in result)
  23.   {
  24.     Console.WriteLine(„—————————„);
  25.     Console.WriteLine(„Id: „ + row.Id.ToString());
  26.     Console.WriteLine(„Name: „ + row.Name);
  27.     Console.WriteLine(„Kategorie: „ + row.Category.ToString());
  28.     Console.WriteLine(„Preis: „ + row.Price.ToString());
  29.   }
  30.   Console.ReadLine();
  31.    }
  32.   private static Product[] GetWebServiceResult(string webSrvUrl, string postData)
  33.    {
  34.   Product[] jsonResponse = null;
  35.   byte[] postBytes = Encoding.UTF8.GetBytes(postData);
  36.   // build web-request
  37.   WebRequest httpWReq = WebRequest.Create(webSrvUrl);
  38.   httpWReq.Credentials = CredentialCache.DefaultCredentials;
  39.   httpWReq.Method = WebRequestMethods.Http.Post;
  40.   httpWReq.ContentType = „application/json“;
  41.   httpWReq.ContentLength = postBytes.Length;
  42.    // build request-stream
  43.   using (Stream dataStream = httpWReq.GetRequestStream())
  44.   {
  45.    dataStream.Write(postBytes, 0, postBytes.Length);
  46.   }

  47.   // get Response
  48.  try
  49.  {
  50.   HttpWebResponse httpWResp = (HttpWebResponsehttpWReq.GetResponse();
  51.   // if response successfully…
  52.   if (httpWResp.StatusCode == HttpStatusCode.OK)
  53.   {
  54.     // …get response-stream…
  55.    using (Stream responseStream = httpWResp.GetResponseStream())
  56.    {
  57.      string responseJson = String.Empty;
  58.      // …read streamReader…
  59.     using (StreamReader reader = new StreamReader               (responseStream))
  60.     {
  61.      responseJson = reader.ReadToEnd();
  62.      // … finally deserialize json (add reference System.Web.Extensions)
  63.      JavaScriptSerializer jsSr = new JavaScriptSerializer();
  64.      jsonResponse = jsSr.Deserialize<Product[]>(responseJson);
  65.     }
  66.    }
  67.   }
  68.   else
  69.   {
  70.     Fail(„Response not successfully!“);
  71.    }
  72.   }
  73.   catch (Exception ex)
  74.   {
  75.    Fail(„Exception: „ + ex.ToString());
  76.   }
  77.   return jsonResponse;
  78.  }
  79.   private static void Fail(string errorMessage)
  80.   {
  81.     Console.WriteLine(errorMessage);
  82.   }
  83.  }
  84. }

Die Main-Methode hat hier nicht mehr zu tun, als die Methode „GetData()“ aufzurufen.

Die Methode „GetData()“ ruft ihrerseits auch nur die Methode „GetWebServiceResult()“ mit der passenden Webservice-URL und der ID-Liste im JSON-Format auf und gibt das deserialisierte Ergebnis auf der Konsole aus.

Weiterhin gibt es noch eine Methode Fail(), welche eine einfache Fehlermeldung zurückgibt wenn der Webservice nicht erfolgreich abgerufen werden konnte.

Der wirklich interessante Teil steckt in der Methode „GetWebServiceResult()“ (Zeile 36 bis 95).
In Zeile 39 wird der String, welcher die Liste der abzurufenden ID’s beinhaltet in ein Byte-Array umgewandelt, damit dieses später dem Request hinzugefügt werden kann.
Anschließend wird ein Web-Request erstellt, welche folgende Eigenschaften hat (Zeile 43 bis 46):

  • Credentials des ausführenden Users verwenden
  • Request-Methode POST verwenden
  • ContentType auf „application/json“ setzen

Es muss dann ein Request-Stream erstellt werden, welcher anschließend in Zeile 49 abgeschickt wird.
Wenn dann der Status „OK“ zurückgegeben wird (Zeile 60) wird die Response als Stream bezogen (Zeilen 63 bis 70). Dies führt letztendlich zu einem lesbaren JSON in der Variable „responseJson“ (Zeile 70).
Diese Variable wird in den Zeilen 73 und 74 wieder zu einem Objekt-Array vom Typ „Product“ deserialisiert.

Fazit

Obwohl es mir nicht gefällt den Webservice derat „low-level“ aufzurufen, bleibt, abgesehen von Drittanbieter-Komponenten keine andere Möglichkeit.
Der nächste Artikel dieser Serie beschäftigt sich dann mit der Adaption des geschriebenen Codes als SSIS-Skript-Task.

Links

[1] http://stackoverflow.com/questions/17483182/calling-web-api-service-from-a-net-2-0-client
[2] https://www.roelvanlisdonk.nl/2013/10/09/how-to-post-a-string-array-to-a-asp-net-web-api-rest-service-that-uses-json-from-a-net-2-0-assembly
[3] https://marketplace.visualstudio.com/items?itemName=ZappySys.SSISRESTAPIWebServiceTask

Schreibe einen Kommentar