Announcement

Collapse
No announcement yet.

Web Servicecs Newbee Fragen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Web Servicecs Newbee Fragen

    Hi
    Ich bin gerade dabei eine Seminararbeit zu erstellen, die sich mit dem Thema .Net befasst. Dabei kommen mir noch so einige Sachen "spanisch" vor und deshalb suche ich auf diesem Wege eure Hilfe.
    Das mit der Sprachübergreifenden Entwicklung und der technischen Umsetzung habe ich ja schon einigermassen begriffen. Mein Problem ist jetzt aber die Interoperabilität. Vielleicht denke ich auch nur in "alten" Strukturen.
    Was Web services bringen sollen, habe ich ja schon gelesen, aber ich verstehe das noch nicht so recht.
    Ich schreibe also ein Programm, welches dann eine solche Schnittstelle hat. Wie kann ich jetzt von woanders diese Funktionen nutzen? Wenn ich das richtig verstanden habe, soll doch diese Schnittstelle dazu dienen, das jetzt von woanders (eventuell ein anderes Programm auf einem anderem Rechner im Web) diese Funktionalität genutzt werden kann. Aber wie geht das jetzt genau vonstatten?
    Im Prinzip würde mir erst mal eine grobe Schematisierung nutzen, damit ich das besser verstehen lerne. Vielleicht habt ihr aber auch irgendwo ein Dokument gefunden, wo es einfach und kurz erklärt ist.

    Danke schon mal im vorraus

    Val

  • #2
    Hallo,

    die Sache mit den Web Services ist eigentlich ganz einfach. Gemäß der Definition der Web Service Description Working Group (W3C) steckt folgendes dahinter: "<i>Ein Web Service ist eine durch eine URI (Uniform Ressource Identifier) identifizierbare Software-Anwendung oder eine Komponente, deren Interfaces (Schnittstellen) dazu dienen, über standardisierte XML-Aufrufe (SOAP) eine direkte Kommunikation zwischen Software-Anwendungen durch das Austauschen von als XML vorliegenden Daten zu ermöglichen, wobei dafür Internet-basierende Protokolle verwendet werden. </i>".

    Wenn mit .NET ein Web Service entwickelt wird (d.h. dieser veröffentlich über das [WebMethod]-Attribut bestimmte Methoden), so kann ein beliebiger Client die WSDL-Information (<i>Web Service Description Language</i>) mit der maschinenlesbaren Schnittstellen-Beschreibung abfordern. Die WSDL ist daher ein plattformunabhängiges Gegenstück zu den <i>Typbibliotheken</i> von COM (Component Object Model). Bei COM baut der Standard-Marshaler von Windows über die maschinenlesbaren Infos aus der Typbibliothek die "Proxy-Klasse" (genauer gesagt, Stub und Proxy) automatisch zusammen. Ein Web Service soll jedoch unabhängig vom Betriebssystem sein, daher schaltet man WSDL als offenen Standard dazwischen und überlässt das Generieren der Proxy-Klassen den jeweiligen Entwicklungsumgebungen. Solange für ein Betriebssystem eine Entwicklungsumgebung verfügbar ist, die die WSDL-Daten "versteht", kann ein beliebiger Client auf den Web Service zugreifen.

    Angenommen, ein Delphi 7-Client (kein .NET, sondern "nur" Win32) importiert diese WSDL-Information. In diesem Fall generiert die Entwicklungsumgebung (Delphi 7) daraus den Sourcecode für die <i>Proxy-Klasse</i>. Diese Proxy-Klasse ist dafür zuständig, die bidirektionale XML-Kommunikation (SOAP) in die eigenen Sprachaufrufe umzusetzen. Mit einem konkreten Beispiel sieht das so aus:

    a) ASP.NET XML Web Service
    <pre>
    [WebMethod]
    <b>public</b> DataSet GetCustomerAsDataSet(<b>string</b> sCity)
    {
    <b>this</b>.bdpDataAdapter1.SelectCommand.Parameters[0].Value = sCity;
    DataSet aDS = <b>new</b> DataSet();
    <b>this</b>.bdpDataAdapter1.Fill(aDS, <font color="#9933CC">&quot;Customer&quot;</font>);
    <b>return</b> aDS;
    }

    [WebMethod]
    <b>public</b> XmlNode GetCustomerAsXmlNode(<b>string</b> sCity)
    {
    <b>return</b> <b>new</b> XmlDataDocument(GetCustomerAsDataSet(sCity));
    }
    </pre>

    b) Delphi 7-Client ruft diesen Web Service auf (beim WSDL-Import wurde die IP-Adresse fest verdrahtet, kann allerdings zur Laufzeit bei Bedarf ersetzt werden) und zeigt die erhaltenen Datenmenge aus dem DataSet in seiner tabellarischen Darstellung über die TDBGrid-Komponente von Delphi an. Dabei sorgt ein Transformer dafür, dass die XML-Daten in das Borland-eigene ClientDataSet-Format konvertiert werden:
    <pre>
    <b>procedure</b> TForm1.Button2Click(Sender: TObject);
    <b>var</b>
    aWS : WebService1Soap;
    sData : <b>String</b>;
    <b>begin</b>
    aWS := GetWebService1Soap;
    sData := aWS.GetCustomerAsXmlNode(EditCity.Text);
    Memo1.Lines.Text := sData;
    XMLTransformProvider1.TransformRead.SourceXml := sData;
    ClientDataSet1.Close;
    ClientDataSet1.Open;
    <b>end</b>;
    </pre>
    Die von Delphi beim Import der WSDL automatisch generierte Proxy-Klasse sieht so aus:
    <pre>
    <font color="#003399"><i>// ************************************************** ********************** //</i></font>
    <font color="#003399"><i>// Die in dieser Datei deklarierten Typen wurden aus Daten generiert, die aus </i></font>
    <font color="#003399"><i>// unten beschriebener WSDL-Datei stammen:</i></font>
    <font color="#003399"><i>// WSDL : http://localhost/OSWSCSBXmlNode/WebService1.asmx?WSDL</i></font>
    <font color="#003399"><i>// Codierung : utf-8</i></font>
    <font color="#003399"><i>// Version : 1.0</i></font>
    <font color="#003399"><i>// (05.10.2003 15:58:13 - 1.33.2.5)</i></font>
    <font color="#003399"><i>// ************************************************** ********************** //</i></font>

    <b>unit</b> WebService1;

    <b>interface</b>

    <b>uses</b> InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;

    <b>type</b>

    <font color="#003399"><i>// ************************************************** ********************** //</i></font>
    <font color="#003399"><i>// Die folgenden Typen, auf die im WSDL-Dokument Bezug genommen wird, sind in dieser Datei</i></font>
    <font color="#003399"><i>// nicht repräsentiert. Sie sind entweder Aliase(@) anderer repräsentierter Typen oder auf sie wurde Bezug genommen,</i></font>
    <font color="#003399"><i>// aber in diesem Dokument nicht deklariert (!). Die Typen aus letzterer Kategorie</i></font>
    <font color="#003399"><i>// sind normalerweise mit vordefinierten/bekannten XML- oder Borland-Typen verbunden; sie könnten aber auch ein Anzeichen </i></font>
    <font color="#003399"><i>// für ein falsches WSDL-Dokument sein, das einen Schema-Typ nicht deklariert oder importiert..</i></font>
    <font color="#003399"><i>// ************************************************** ********************** //</i></font>
    <font color="#003399"><i>// !:string - &quot;http://www.w3.org/2001/XMLSchema&quot;</i></font>

    GetCustomerAsDataSetResult = <b>class</b>; <font color="#003399"><i>{ &quot;http://tempuri.org/&quot; }</i></font>

    <font color="#003399"><i>// ************************************************** ********************** //</i></font>
    <font color="#003399"><i>// Namespace : http://tempuri.org/</i></font>
    <font color="#003399"><i>// ************************************************** ********************** //</i></font>
    GetCustomerAsDataSetResult = <b>class</b>(TRemotable)
    <b>private</b>
    Fschema: WideString;
    <b>published</b>
    <b>property</b> schema: WideString <b>read</b> Fschema <b>write</b> Fschema;
    <b>end</b>;

    GetCustomerAsXmlNodeResult = <b>type</b> WideString; <font color="#003399"><i>{ &quot;http://tempuri.org/&quot; }</i></font>

    <font color="#003399"><i>// ************************************************** ********************** //</i></font>
    <font color="#003399"><i>// Namespace : http://tempuri.org/</i></font>
    <font color="#003399"><i>// soapAction: http://tempuri.org/%operationName%</i></font>
    <font color="#003399"><i>// Transport : http://schemas.xmlsoap.org/soap/http</i></font>
    <font color="#003399"><i>// Stil : document</i></font>
    <font color="#003399"><i>// Bindung : WebService1Soap</i></font>
    <font color="#003399"><i>// Service : WebService1</i></font>
    <font color="#003399"><i>// Port : WebService1Soap</i></font>
    <font color="#003399"><i>// URL : http://localhost/OSWSCSBXmlNode/WebService1.asmx</i></font>
    <font color="#003399"><i>// ************************************************** ********************** //</i></font>
    WebService1Soap = <b>interface</b>(IInvokable)
    [<font color="#9933CC">'{3392229C-09D2-6D56-CE62-6850ABB2629D}'</font>]
    <b>function</b> GetCustomerAsDataSet(<b>const</b> sCity: WideString): GetCustomerAsDataSetResult; <b>stdcall</b>;
    <b>function</b> GetCustomerAsXmlNode(<b>const</b> sCity: WideString): GetCustomerAsXmlNodeResult; <b>stdcall</b>;
    <b>end</b>;

    <b>function</b> GetWebService1Soap(UseWSDL: Boolean=System.False; Addr: <b>string</b>=<font color="#9933CC">''</font>; HTTPRIO: THTTPRIO = <b>nil</b>): WebService1Soap;

    <b>implementation</b>

    <b>function</b> GetWebService1Soap(UseWSDL: Boolean; Addr: <b>string</b>; HTTPRIO: THTTPRIO): WebService1Soap;
    <b>const</b>
    defWSDL = <font color="#9933CC">'http://localhost/OSWSCSBXmlNode/WebService1.asmx?WSDL'</font>;
    defURL = <font color="#9933CC">'http://localhost/OSWSCSBXmlNode/WebService1.asmx'</font>;
    defSvc = <font color="#9933CC">'WebService1'</font>;
    defPrt = <font color="#9933CC">'WebService1Soap'</font>;
    <b>var</b>
    RIO: THTTPRIO;
    <b>begin</b>
    Result := <b>nil</b>;
    <b>if</b> (Addr = <font color="#9933CC">''</font>) <b>then</b>
    <b>begin</b>
    <b>if</b> UseWSDL <b>then</b>
    Addr := defWSDL
    <b>else</b>
    Addr := defURL;
    <b>end</b>;
    <b>if</b> HTTPRIO = <b>nil</b> <b>then</b>
    RIO := THTTPRIO.Create(<b>nil</b>)
    <b>else</b>
    RIO := HTTPRIO;
    <b>try</b>
    Result := (RIO <b>as</b> WebService1Soap);
    <b>if</b> UseWSDL <b>then</b>
    <b>begin</b>
    RIO.WSDLLocation := Addr;
    RIO.Service := defSvc;
    RIO.Port := defPrt;
    <b>end</b> <b>else</b>
    RIO.URL := Addr;
    <b>finally</b>
    <b>if</b> (Result = <b>nil</b>) <b>and</b> (HTTPRIO = <b>nil</b>) <b>then</b>
    RIO.Free;
    <b>end</b>;
    <b>end</b>;

    <b>initialization</b>
    InvRegistry.RegisterInterface(TypeInfo(WebService1 Soap), <font color="#9933CC">'http://tempuri.org/'</font>, <font color="#9933CC">'utf-8'</font>);
    InvRegistry.RegisterDefaultSOAPAction(TypeInfo(Web Service1Soap), <font color="#9933CC">'http://tempuri.org/%operationName%'</font>);
    InvRegistry.RegisterInvokeOptions(TypeInfo(WebServ ice1Soap), ioDocument);
    RemClassRegistry.RegisterXSClass(GetCustomerAsData SetResult, <font color="#9933CC">'http://tempuri.org/'</font>, <font color="#9933CC">'GetCustomerAsDataSetResult'</font>);
    RemClassRegistry.RegisterXSInfo(TypeInfo(GetCustom erAsXmlNodeResult), <font color="#9933CC">'http://tempuri.org/'</font>, <font color="#9933CC">'GetCustomerAsXmlNodeResult'</font>);

    <b>end</b>.
    </pre&gt

    Comment


    • #3
      Ich habe da auch noch eine Frage:<p>
      Kann man eigentlich überhaupt <b>keine statischen arrays</b> als Parameter bei einem Web-Services Aufruf übergeben???<p>
      Ich möchte gern folgendes realisieren:<p><pre>
      type
      TColor = (red, blue, green);
      TColArr = array[TColor, 1..2] of integer;

      procedure test(aArr: TColArr);
      </pre>

      <p>
      Als dynamische Arrays (array of integer) ist das ja alles schön machbar - aber gibt es in Web-Services eine Möglichkeit für statische arrays??

      Comment


      • #4
        Hallo,

        wenn man sich selbst darum kümmert, dass in der WSDL die XML Schema-Beschreibung der eigenen Strukturen erscheint, kann man alles Mögliche (solange kein Feature genutzt wird, dass nur in einer Sprache vorkommt) übertragen. Das folgende Beispiel demonstriert dies, hier sorgen die <b>SoapRpcMethod</b>- und <b>SoapInclude</b>-Attribute dafür, dass die Beschreibung in die WSDL aufgenommen wird:
        <pre>
        <WebMethod(Description:="Liefert entweder OSWinUser oder OSWebUser als Nachfahre von OSComplexData zurück"), _
        SoapRpcMethod(), SoapInclude(GetType(OSWinUser)), SoapInclude(GetType(OSWebUser))> _
        Public Function GetInstance(ByVal iValue As Integer) As OSComplexData
        Select Case iValue
        Case 1
        Dim aNewObj As New OSWinUser()
        aNewObj.LogonTime = Date.Now()
        Return aNewObj
        Case 2
        Dim aNewObj As New OSWebUser()
        aNewObj.UserName = Me.User.Identity.Name
        aNewObj.UserKey = 4711
        aNewObj.HomePage = "http://www.entwickler.com"
        Return aNewObj
        End Select
        End Function
        </pre&gt

        Comment

        Working...
        X