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 spezifiziert werden kann, ohne dass zusätzliche Codierung erforderlich wäre, um den Inhalt des DataSet zu einem Client zu streamen und wieder zurück. Der DataSet wird implizit in einen XML-Datenstrom im DiffGram-Format konvertiert, über das Netzwerk gesendet und dann aus dem XML-Datenstrom als DataSet am Empfangsende 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, die das DataSet nutzen, um relationale Daten (einschließlich geänderter Daten) zu transportieren und alle Aktualisierungen zurück zur ursprünglichen Datenquelle aufzulö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 empfängt ein DataSet mit Aktualisierungen der Daten, die der XML-Webdienst wieder in die ursprüngliche Datenquelle integriert.

    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 optimistische Synchronisationsfehler 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 Webdienstproxyklasse für Sie generieren soll, erstellen Sie einfach das Clientprojekt, und klicken Sie im Projektmappen-Explorer-Fenster mit der rechten Maustaste auf das Projekt, und wählen Sie dann Add" 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, fügt einen neuen Kunden hinzu und gibt dann eine DataSet mit den Updates für UpdateCustomers zurück.

    Das Beispiel übergibt das von DataSet zurückgegebene an UpdateCustomers, da nur geänderte Zeilen an UpdateCustomers übergeben werden müssen. UpdateCustomers gibt das aufgelöste DataSet zurück, das Sie dann Merge in das vorhandene DataSet Datenset einfügen 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