Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs

Web Services in Anwendungen konsumieren

Geschrieben von: Christoph Wille
Kategorie: Web Services

This printed page brought to you by AlphaSierraPapa

Im Artikel Web Services 101 in ASP.NET habe ich gezeigt, wie einfach es ist, einen Web Service zu programmieren. Heute begeben wir uns auf die andere Seite der Front, nämlich auf die Kundenseite: wir wollen lernen, wie man einen Web Service anspricht und seine Funktionen aufruft - ihn "konsumiert".

Ich möchte speziell darauf hinweisen, daß obwohl wir heute exemplarisch einen in .NET geschriebenen Web Service konsumieren, die vorgestellte Vorgehensweise für alle zu SOAP und WSDL kompatiblen Web Service Implementierungen gilt: sei dieser in Perl auf Linux, Java auf Solaris oder welcher Kombination Sprache und Betriebssystem auch immer programmiert.

Um den heute vorgestellten Code ausführen zu können, muß ASP.NET am Server installiert sein. Für das Erstellen von Assemblies benötigt man das vollständige .NET SDK (nicht notwendigerweise am Server, allerdings auf der Maschine, auf der die Assembly kompiliert werden soll).

Unser Web Service

Bevor man einen Web Service konsumieren kann, braucht man zuerst einen solchen. Damit wir ein nettes kleines Beispiel zum Probieren haben, wiederverwende ich die VB Implementierung unserer Services aus dem Artikel Web Services 101 in ASP.NET. Hier nochmals der Web Service (SampleVBService.asmx):

<%@ WebService Language="VB" Class="DemoVBService" %>
Imports System
Imports System.Web.Services

Public Class DemoVBService : Inherits WebService
 <WebMethod()> Public Function SayHello(strName As System.String) As System.String
  SayHello = "Hello " & strName & " from VB" 
 End Function
End Class

Legen Sie diese ASMX Datei auf Ihrem Web Server ab, und wir können beginnen.

Der Web Service Proxy

Wer COM mit C++ programmiert hat, kennt das Prinzip der Proxies und Stubs: ein Objekt "lebt" auf einer einzigen (Server-)Maschine, und um es auf anderen Maschinen gleich aufrufen zu können wie wenn es lokal installiert wäre, gibt es Proxies und Stubs - und diese funktionieren wie folgt: auf der lokalen Maschine wird von COM ein Proxy erstellt, der für den Client wie das echte Objekt aussieht. Aber eben nur so aussieht. Hinter jeder Funktion steht COM, das den Aufruf an die Maschine marshalled (weiterleitet), auf der das echte Objekt lebt. Dort nimmt der von COM erstellte Stub die Daten an, und spricht mit dem Objekt wie wenn es der Client wäre. Ist der Aufruf beendet, gehen die Rückgabewerte den Weg Objekt-Stub-Proxy-Client zurück. Und der Client wußte nie von seinem Glück.

Eine Frage drängt sich auf - woher weiß COM, welche Funktionen für das Objekt existieren, um die Dummyfunktionen des Proxy's und des Stub's zu erstellen? Nun, dafür gibt es die Type Libraries. Diese enthalten Informationen über die Typen und Methoden der Objekte, und aus diesen Informationen kann COM die Proxies und Stubs automatisch erstellen.

Wieso dieser Ausflug nach COM? Nun, bei .NET Web Services läuft die Sache nämlich sehr ähnlich ab. Wie wir wissen, ist jeder Web Service über WSDL definiert - und dieses WSDL ist das Type Library-Äquivalent von COM, mit dem .NET für uns einen Web Service Proxy am Client erstellt.

Dieses Erstellen des Proxy's läuft allerdings (meist) vor dem Benutzen des Services ab, da im Gegensatz zur Type Library von COM das WSDL nicht am Client vorliegt - und extra dafür erst aufs Web zu gehen ist ineffizient. Daher wird der Proxy vorgeneriert, und zwar mit Hilfe des Wsdl.exe Utility's (CreateProxy.bat als Beispiel):

Wsdl /language:cs  /protocol:soap /namespace:AspHeuteProxy /out:AspHeuteProxy.cs 
     http://192.168.1.203/ConsumeService/SampleVBService.asmx

Was ist nun beim Aufruf von Wsdl.exe zu beachten? Nun, der URL des Web Services ist das absolut wichtigste dabei, weil er in die Proxyklasse (in unserem Fall in C# erstellt, im Namespace AspHeuteProxy, Name ident zum Klassennamen des Web Services) aufgenommen wird. Was ich damit sagen will ist daß wenn sich der URL eines Web Services ändert, ich die Klasse regenerieren muß. Das sollte man nie vergessen.

Die Datei AspHeuteProxy.cs ist jeder eingeladen, sich durchzusehen. Ich hingegen werde mit der Implementierung der Clients anfangen.

Ein Kommandozeilen Client

Beginnen wir einfach - eine kleine Kommandozeilenapplikation in C# geschrieben, die den Service aufruft, und das Ergebnis an der Console ausgibt. Dazu habe ich wieder einmal SharpDevelop verwendet, das ein Template für Konsolenanwendungen hat. Man muß nur die Datei AspHeuteProxy.cs zum Projekt hinzufügen:

Dann gehe ich daran, die vorgenerierte Main.cs zu verändern (Änderungen kursiv):

using System;
using AspHeuteProxy;

class MainClass
{
  public static void Main(string[] args)
  {
    DemoVBService myService = new DemoVBService();
    Console.WriteLine(myService.SayHello("Christoph"));
  }
}

Nur drei Zeilen sind notwendig, um einen Web Service aufzurufen! Den Rest erledigt der Proxy von .NET im Hintergrund für uns, und für uns sieht es aus, als würden wir mit einer lokal installierten Komponente arbeiten. Und ja, für nicht .NET Web Services funktioniert das genau gleich.

Eine ASP.NET Seite als Client

Nun, eine Kommandozeilenapplikationen ist zwar nett und schön, aber wie wär's, wenn wir den Web Service in unseren ASP.NET Seiten einsetzen könnten? Aber sicher doch. Dazu muß man aber den Verwendungsansatz des Proxy's leicht verändern - man muß ihn in eine Assembly verpacken. Dies geht jedoch sehr, sehr einfach (Compile.bat)

csc.exe /target:library AspHeuteProxy.cs

Die resultierende AspHeuteProxy.dll Assembly verfrachtet man dann in das bin Verzeichnis der gewünschten Web Applikation, und schon kann man den Web Service aufrufen. Ich habe dazu ein minimales Formular mit einer Textbox, Schaltfläche und Label gebaut (der Label dient der Anzeige des Rückgabeergebnisses des Web Services):

Und hier nun der Code dazu (CallService.aspx):

<% @Import Namespace="AspHeuteProxy" %>
<script language="C#" runat="server">
void btnPress_Click(Object Sender, EventArgs E)
{
  DemoVBService myService = new DemoVBService();
  lblHelloOut.Text = myService.SayHello(txtMessage.Text);
}
</script>

<html>
<body>

<form runat="server">

<asp:textbox id="txtMessage" runat="server"/>
<asp:Button id="btnPress" text="Say Hello!" onClick="btnPress_Click" runat="server" />

<p>
<asp:Label id="lblHelloOut" text="" runat="server" />
</p>

</form>

</body>
</html>

Der Code ist der gleiche wie der der Kommandozeilenapplikation, nur befindet er sich in der Ereignisprozedur des Buttons des Formulars. Alles, was ich tun mußte, war das @Import Statement für den Namespace des Proxy's einzufügen. Üblicherweise würde der Benutzer vom Aufruf eines Web Services nichts mitbekommen (zB Kreditkartenvalidierung in Echtzeit), aber heute begnügen wir uns mal mit einer "interaktiven Spielwiese" für den Web Service.

Übrigens - da der Proxy jetzt als Assembly vorliegt, kann ich die ASP.NET Seite klarerweise auch in VB.NET schreiben (CallService_vbnet.aspx - der Formularcode ist identisch):

<% @Import Namespace="AspHeuteProxy" %>
<script language="VB" runat="server">
Sub btnPress_Click(Sender as Object, E as EventArgs)
  Dim myService As DemoVBService 
  myService = New DemoVBService
  lblHelloOut.Text = myService.SayHello(txtMessage.Text)
End sub
</script>

Der Web Service ist in VB.NET implementiert, der Proxy in C# erstellt, und die ASP.NET Seite läuft wieder in VB.NET. Ein netter Sprachenmix, der zeigt, wie "freundlich" .NET gegenüber Teams mit unterschiedlichen Sprachpräferenzen ist.

Schlußbemerkung

Damit hätten wir den ersten Schritt zur Verwendung von Web Services getan. Uns fehlt etwas, das ein späterer Artikel nachholen wird: Fehlerbehandlung für den Fall, daß der Server mit dem Web Service nicht erreichbar sein sollte.

This printed page brought to you by AlphaSierraPapa

Download des Codes

Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20010622.zip

Verwandte Artikel

Amazon.com Web Services 2.0
http:/www.aspheute.com/artikel/20021029.htm
Authentifizierung in Web Services - Windows Integrated
http:/www.aspheute.com/artikel/20030429.htm
Index Server Abfragen per Web Service
http:/www.aspheute.com/artikel/20021107.htm
Programmieren mit den Google Web APIs Beta 2
http:/www.aspheute.com/artikel/20020415.htm
Session State in ASP.NET Web Services
http:/www.aspheute.com/artikel/20010627.htm
Web Projekte mit SharpDevelop erstellen
http:/www.aspheute.com/artikel/20010208.htm
Web Services 101 in ASP.NET
http:/www.aspheute.com/artikel/20010621.htm
Web Services mit dem SOAP Toolkit erstellen
http:/www.aspheute.com/artikel/20010629.htm

Links zu anderen Sites

DotNetGerman Diskussionslisten
http://www.dotnetgerman.com/
SharpDevelop
http://www.icsharpcode.net/opensource/sd/

 

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.