Freigeben über


Verwenden eines Datasets aus einem XML-Webdienst

Das DataSet wurde mit einer nicht verbundenen Struktur erstellt. Auf diese Art und Weise wird z. B. eine komfortable Übertragung von Daten über das Internet ermöglicht. Das DataSet ist "serialisierbar", da es als Eingabe oder Ausgabe von XML-Webdiensten angegeben werden kann, ohne dass zusätzliche Codierung erforderlich ist, um den Inhalt des DataSets von einem XML-Webdienst auf einen Client und zurück zu streamen. Das DataSet wird implizit in einen XML-Datenstrom mit dem DiffGram-Format konvertiert, über das Netzwerk gesendet und dann aus dem XML-Datenstrom als DataSet am empfangenden Ende rekonstruiert. Dadurch erhalten Sie eine einfache und flexible Methode zum Übertragen und Zurückgeben relationaler Daten mithilfe von XML-Webdiensten. Weitere Informationen zum DiffGram-Format finden Sie unter DiffGrams.

Das folgende Beispiel zeigt, wie Sie einen XML-Webdienst und einen Client erstellen, der das DataSet zum Transport relationaler Daten (einschließlich geänderter Daten) verwendet, und alle Aktualisierungen zurück zur ursprünglichen Datenquelle auflösen.

Hinweis

Das Übertragen DataSet oder DataTable Instanzen als Teil von XML-Webdienstaufrufen ist nicht sicher, wenn die Eingabe nicht vertrauenswürdig ist. Weitere Informationen finden Sie im Sicherheitsleitfaden für DataSet und DataTable. Außerdem wird empfohlen, beim Erstellen eines XML-Webdiensts immer Sicherheitsauswirkungen zu berücksichtigen. Informationen zum Sichern eines XML-Webdiensts finden Sie unter Sichern von XML-Webdiensten, die mit ASP.NET erstellt wurden.

Erstellen eines XML-Webdiensts

  1. Erstellen Sie den XML-Webdienst.

    Im Beispiel wird ein XML-Webdienst erstellt, der Daten zurückgibt, in diesem Fall eine Liste von Kunden aus der Northwind-Datenbank und ein DataSet mit Aktualisierungen an den Daten empfängt, die der XML-Webdienst wieder in die ursprüngliche Datenquelle aufgelöst.

    Der XML-Webdienst macht zwei Methoden verfügbar: GetCustomers, um die Liste der Kunden zurückzugeben, und UpdateCustomers, um Aktualisierungen zurück an die Datenquelle zu beheben. Der XML-Webdienst wird in einer Datei auf dem Webserver namens DataSetSample.asmx gespeichert. Der folgende Code beschreibt den Inhalt von DataSetSample.asmx.

    <% @ WebService Language = "vb" Class = "Sample" %>  
    Imports System  
    Imports System.Data  
    Imports System.Data.SqlClient  
    Imports System.Web.Services  
    
    <WebService(Namespace:="http://microsoft.com/webservices/")> _  
    Public Class Sample  
    
    Public connection As SqlConnection = New SqlConnection("Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind")  
    
      <WebMethod( Description := "Returns Northwind Customers", EnableSession := False )> _  
      Public Function GetCustomers() As DataSet  
        Dim adapter As SqlDataAdapter = New SqlDataAdapter( _  
          "SELECT CustomerID, CompanyName FROM Customers", connection)  
    
        Dim custDS As DataSet = New DataSet()  
        adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey  
        adapter.Fill(custDS, "Customers")  
    
        Return custDS  
      End Function  
    
      <WebMethod( Description := "Updates Northwind Customers", EnableSession := False )> _  
      Public Function UpdateCustomers(custDS As DataSet) As DataSet  
        Dim adapter As SqlDataAdapter = New SqlDataAdapter()  
    
        adapter.InsertCommand = New SqlCommand( _  
          "INSERT INTO Customers (CustomerID, CompanyName) " & _  
          "Values(@CustomerID, @CompanyName)", connection)  
        adapter.InsertCommand.Parameters.Add( _  
          "@CustomerID", SqlDbType.NChar, 5, "CustomerID")  
        adapter.InsertCommand.Parameters.Add( _  
          "@CompanyName", SqlDbType.NChar, 15, "CompanyName")  
    
        adapter.UpdateCommand = New SqlCommand( _  
          "UPDATE Customers Set CustomerID = @CustomerID, " & _  
          "CompanyName = @CompanyName WHERE CustomerID = " & _  
          @OldCustomerID", connection)  
        adapter.UpdateCommand.Parameters.Add( _  
          "@CustomerID", SqlDbType.NChar, 5, "CustomerID")  
        adapter.UpdateCommand.Parameters.Add( _  
          "@CompanyName", SqlDbType.NChar, 15, "CompanyName")  
    
        Dim parameter As SqlParameter = _  
          adapter.UpdateCommand.Parameters.Add( _  
          "@OldCustomerID", SqlDbType.NChar, 5, "CustomerID")  
        parameter.SourceVersion = DataRowVersion.Original  
    
        adapter.DeleteCommand = New SqlCommand( _  
          "DELETE FROM Customers WHERE CustomerID = @CustomerID", _  
          connection)  
        parameter = adapter.DeleteCommand.Parameters.Add( _  
          "@CustomerID", SqlDbType.NChar, 5, "CustomerID")  
        parameter.SourceVersion = DataRowVersion.Original  
    
        adapter.Update(custDS, "Customers")  
    
        Return custDS  
      End Function  
    End Class  
    
    <% @ WebService Language = "C#" Class = "Sample" %>  
    using System;  
    using System.Data;  
    using System.Data.SqlClient;  
    using System.Web.Services;  
    
    [WebService(Namespace="http://microsoft.com/webservices/")]  
    public class Sample  
    {  
      public SqlConnection connection = new SqlConnection("Data Source=(local);Integrated Security=SSPI;Initial Catalog=Northwind");  
    
      [WebMethod( Description = "Returns Northwind Customers", EnableSession = false )]  
      public DataSet GetCustomers()  
      {  
        SqlDataAdapter adapter = new SqlDataAdapter(  
          "SELECT CustomerID, CompanyName FROM Customers", connection);  
    
        DataSet custDS = new DataSet();  
        adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;  
        adapter.Fill(custDS, "Customers");  
    
        return custDS;  
      }  
    
      [WebMethod( Description = "Updates Northwind Customers",  
        EnableSession = false )]  
      public DataSet UpdateCustomers(DataSet custDS)  
      {  
        SqlDataAdapter adapter = new SqlDataAdapter();  
    
        adapter.InsertCommand = new SqlCommand(  
          "INSERT INTO Customers (CustomerID, CompanyName) " +  
          "Values(@CustomerID, @CompanyName)", connection);  
        adapter.InsertCommand.Parameters.Add(  
          "@CustomerID", SqlDbType.NChar, 5, "CustomerID");  
        adapter.InsertCommand.Parameters.Add(  
          "@CompanyName", SqlDbType.NChar, 15, "CompanyName");  
    
        adapter.UpdateCommand = new SqlCommand(  
          "UPDATE Customers Set CustomerID = @CustomerID, " +  
          "CompanyName = @CompanyName WHERE CustomerID = " +  
          "@OldCustomerID", connection);  
        adapter.UpdateCommand.Parameters.Add(  
          "@CustomerID", SqlDbType.NChar, 5, "CustomerID");  
        adapter.UpdateCommand.Parameters.Add(  
          "@CompanyName", SqlDbType.NChar, 15, "CompanyName");  
        SqlParameter parameter = adapter.UpdateCommand.Parameters.Add(  
          "@OldCustomerID", SqlDbType.NChar, 5, "CustomerID");  
        parameter.SourceVersion = DataRowVersion.Original;  
    
        adapter.DeleteCommand = new SqlCommand(  
        "DELETE FROM Customers WHERE CustomerID = @CustomerID",  
         connection);  
        parameter = adapter.DeleteCommand.Parameters.Add(  
          "@CustomerID", SqlDbType.NChar, 5, "CustomerID");  
        parameter.SourceVersion = DataRowVersion.Original;  
    
        adapter.Update(custDS, "Customers");  
    
        return custDS;  
      }  
    }  
    

    In einem typischen Szenario würde die UpdateCustomers-Methode geschrieben, um Verletzungen der vollständigen Parallelität abzufangen. Der Einfachheit halber enthält das Beispiel dies nicht. Weitere Informationen zur optimistischen Parallelität finden Sie unter "Optimistische Parallelität".

  2. Erstellen Sie einen XML-Webdienstproxy.

    Clients des XML-Webdiensts erfordern einen SOAP-Proxy, um die verfügbar gemachten Methoden zu nutzen. Visual Studio kann diesen Proxy für Sie generieren lassen. Durch Festlegen eines Webverweises auf einen vorhandenen Webdienst in Visual Studio erfolgt das gesamte in diesem Schritt beschriebene Verhalten transparent. Wenn Sie die Proxyklasse selbst erstellen möchten, fahren Sie mit dieser Diskussion fort. In den meisten Fällen reicht die Verwendung von Visual Studio zum Erstellen der Proxyklasse für die Clientanwendung jedoch aus.

    Ein Proxy kann mit dem Web Services Description Language Tool erstellt werden. Wenn z. B. der XML-Webdienst unter der URL http://myserver/data/DataSetSample.asmxverfügbar gemacht wird, geben Sie einen Befehl aus, z. B. den folgenden Befehl, um einen Visual Basic .NET-Proxy mit einem Namespace von WebData.DSSample zu erstellen und in der Datei sample.vb zu speichern.

    wsdl /l:VB -out:sample.vb http://myserver/data/DataSetSample.asmx /n:WebData.DSSample  
    

    Um einen C#-Proxy in der Datei sample.cs zu erstellen, geben Sie den folgenden Befehl aus.

    wsdl -l:CS -out:sample.cs http://myserver/data/DataSetSample.asmx -n:WebData.DSSample  
    

    Der Proxy kann dann als Bibliothek kompiliert und in den XML-Webdienstclient importiert werden. Um den visual Basic .NET-Proxycode zu kompilieren, der in sample.vb als sample.dllgespeichert ist, geben Sie den folgenden Befehl aus.

    vbc -t:library -out:sample.dll sample.vb -r:System.dll -r:System.Web.Services.dll -r:System.Data.dll -r:System.Xml.dll  
    

    Um den in sample.cs als sample.dllgespeicherten C#-Proxycode zu kompilieren, geben Sie den folgenden Befehl aus.

    csc -t:library -out:sample.dll sample.cs -r:System.dll -r:System.Web.Services.dll -r:System.Data.dll -r:System.Xml.dll  
    
  3. Erstellen Sie einen XML-Webdienstclient.

    Wenn Visual Studio die Proxy-Klasse für den Webdienst für Sie generieren soll, erstellen Sie einfach das Clientprojekt und klicken Sie im Fenster des Projektmappen-Explorers mit der rechten Maustaste auf das Projekt. Wählen Sie dann "Dienstverweis>" aus. Wählen Sie im Dialogfeld " Dienstreferenz hinzufügen " die Option "Erweitert" und dann " Webverweis hinzufügen" aus. Wählen Sie den Webdienst aus der Liste der verfügbaren Webdienste aus (dies kann die Angabe der Adresse des Webdienstendpunkts erfordern, wenn der Webdienst in der aktuellen Lösung oder auf dem aktuellen Computer nicht verfügbar ist). Wenn Sie den XML-Webdienstproxy selbst erstellen (wie im vorherigen Schritt beschrieben), können Sie ihn in Ihren Clientcode importieren und die XML-Webdienstmethoden verwenden.

    Der folgende Beispielcode importiert die Proxybibliothek, ruft GetCustomers auf, um eine Liste von Kunden abzurufen, einen neuen Kunden hinzufügt und dann ein DataSet mit den Updates für UpdateCustomers zurückgibt.

    Das Beispiel übergibt das von DataSet.GetChanges zurückgegebene DataSet an UpdateCustomers, da nur geänderte Zeilen an UpdateCustomers übergeben werden müssen. UpdateCustomers gibt das aufgelöste DataSet zurück, das Sie dann mit dem vorhandenen DataSetzusammenführen können, um die aufgelösten Änderungen und alle Zeilenfehlerinformationen aus der Aktualisierung zu integrieren. Im folgenden Code wird davon ausgegangen, dass Sie Visual Studio zum Erstellen des Webverweises verwendet haben und den Webverweis im Dialogfeld " Webverweis hinzufügen " in "DsSample" umbenannt haben.

    Imports System  
    Imports System.Data  
    
    Public Class Client  
    
      Public Shared Sub Main()  
        Dim proxySample As New DsSample.Sample ()  ' Proxy object.  
        Dim customersDataSet As DataSet = proxySample.GetCustomers()  
        Dim customersTable As DataTable = _  
          customersDataSet.Tables("Customers")  
    
        Dim rowAs DataRow = customersTable.NewRow()  
        row("CustomerID") = "ABCDE"  
        row("CompanyName") = "New Company Name"  
        customersTable.Rows.Add(row)  
    
        Dim updateDataSet As DataSet = _  
          proxySample.UpdateCustomers(customersDataSet.GetChanges())  
    
        customersDataSet.Merge(updateDataSet)  
        customersDataSet.AcceptChanges()  
      End Sub  
    End Class  
    
    using System;  
    using System.Data;  
    
    public class Client  
    {  
      public static void Main()  
      {  
        Sample proxySample = new DsSample.Sample();  // Proxy object.  
        DataSet customersDataSet = proxySample.GetCustomers();  
        DataTable customersTable = customersDataSet.Tables["Customers"];  
    
        DataRow row = customersTable.NewRow();  
        row["CustomerID"] = "ABCDE";  
        row["CompanyName"] = "New Company Name";  
        customersTable.Rows.Add(row);  
    
        DataSet updateDataSet = new DataSet();  
    
        updateDataSet =
          proxySample.UpdateCustomers(customersDataSet.GetChanges());  
    
        customersDataSet.Merge(updateDataSet);  
        customersDataSet.AcceptChanges();  
      }  
    }  
    

    Wenn Sie die Proxyklasse selbst erstellen möchten, müssen Sie die folgenden zusätzlichen Schritte ausführen. Geben Sie zum Kompilieren des Beispiels die Proxybibliothek an, die erstellt wurde (sample.dll) und die zugehörigen .NET-Bibliotheken. Um die Visual Basic .NET-Version des Beispiels zu kompilieren, die in der Datei client.vb gespeichert ist, geben Sie den folgenden Befehl aus.

    vbc client.vb -r:sample.dll -r:System.dll -r:System.Data.dll -r:System.Xml.dll -r:System.Web.Services.dll  
    

    Um die C#-Version des Beispiels zu kompilieren, die in der Datei client.cs gespeichert ist, geben Sie den folgenden Befehl aus.

    csc client.cs -r:sample.dll -r:System.dll -r:System.Data.dll -r:System.Xml.dll -r:System.Web.Services.dll  
    

Siehe auch