共用方式為


從 XML Web 服務使用資料集

DataSet 採用了分散式設計,部分目的是為了更方便地通過互聯網傳輸數據。 DataSet 是「可串行化」的,因為它可以指定為 XML Web 服務的輸入或輸出,而不需要任何額外的程式代碼,即可將 DataSet 的內容從 XML Web 服務串流至用戶端和返回。 DataSet 會使用 DiffGram 格式以隱含方式轉換成 XML 數據流、透過網路傳送,然後從 XML 數據流重新建構為接收端上的 DataSet。 這可讓您使用 XML Web 服務來傳輸和傳回關係型數據,提供簡單且靈活的方法。 如需 DiffGram 格式的詳細資訊,請參閱 DiffGrams

下列範例示範如何建立 XML Web 服務和用戶端,以使用 DataSet 傳輸關係型數據(包括已修改的數據),並將任何更新解析回原始數據源。

備註

傳輸DataSetDataTable實例作為XML Web服務呼叫的一部分,如果輸入不受信任,將是不安全的。 如需詳細資訊,請參閱 DataSet 和 DataTable 安全性指導。 我們也建議您在建立 XML Web 服務時一律考慮安全性影響。 如需保護 XML Web 服務的資訊,請參閱 保護使用 ASP.NET 建立的 XML Web 服務

建立 XML Web 服務

  1. 建立 XML Web 服務。

    在此範例中,會建立會傳回數據的 XML Web 服務,在此案例中為 Northwind 資料庫中的客戶清單,並接收具有數據更新的 DataSet,XML Web 服務會解析回原始數據源。

    XML Web 服務會公開兩種方法: GetCustomers、傳回客戶清單,以及 UpdateCustomers,以將更新解析回數據源。 XML Web 服務會儲存在名為 DataSetSample.asmx 的網頁伺服器上檔案中。 下列程式代碼概述 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;  
      }  
    }  
    

    在一般案例中, UpdateCustomers 方法會寫入以攔截開放式並行違規。 為了簡單起見,此範例不包含此專案。 如需關於樂觀並發控制的詳細資訊,請參閱 樂觀並發控制

  2. 建立 XML Web 服務 Proxy。

    XML Web 服務的用戶端需要SOAP Proxy才能取用公開的方法。 您可以讓 Visual Studio 為您產生此 Proxy。 藉由從 Visual Studio 中設定現有 Web 服務的 Web 參考,此步驟中所述的所有行為都會以透明方式進行。 如果您想要自行建立 Proxy 類別,請繼續進行此討論。 不過,在大部分情況下,使用 Visual Studio 建立用戶端應用程式的 Proxy 類別就已足夠。

    您可以使用 Web 服務描述語言工具建立 Proxy。 例如,如果 XML Web 服務在 URL http://myserver/data/DataSetSample.asmx公開,請發出下列命令,以建立具有 WebData.DSSample 命名空間的 Visual Basic .NET Proxy,並將它儲存在檔案sample.vb中。

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

    若要在檔案sample.cs中建立 C# Proxy,請發出下列命令。

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

    然後,可以將 Proxy 編譯為連結庫,並匯入至 XML Web 服務用戶端。 若要將儲存在 sample.vb 中的 Visual Basic .NET Proxy 程式代碼編譯為 sample.dll,請發出下列命令。

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

    若要將儲存在 sample.cs 中的 C# Proxy 程式代碼編譯為 sample.dll,請發出下列命令。

    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. 建立 XML Web 服務用戶端。

    如果您想要讓 Visual Studio 為您產生 Web 服務 Proxy 類別,只要建立用戶端專案,然後在 [方案總管] 視窗中,以滑鼠右鍵按兩下專案,然後選取 [ 新增>服務參考]。 在 [ 新增服務參考 ] 對話框中,選取 [ 進階],然後選取 [新增 Web 參考]。 從可用的 Web 服務清單中選取 Web 服務(如果目前方案或目前電腦上無法使用 Web 服務,可能需要提供 Web 服務端點的位址)。 如果您自行建立 XML Web 服務 Proxy(如上一個步驟所述),您可以將它匯入用戶端程式代碼,並取用 XML Web 服務方法。

    下列範例程式碼會匯入代理庫,呼叫 GetCustomers 以取得客戶清單,新增一位新客戶,然後使用更新返回一個包含更新的 DataSetUpdateCustomers

    此範例會將DataSet.GetChanges傳回的DataSet傳遞至UpdateCustomers,因為只需要將修改的數據列傳遞至UpdateCustomersUpdateCustomers 會傳回已解析的 DataSet,然後您可以 合併 至現有的 DataSet ,以合併已解析的變更,以及更新中的任何數據列錯誤資訊。 下列程式代碼假設您已使用 Visual Studio 建立 Web 參考,而且您已在 [ 新增 Web 參考 ] 對話框中將 Web 參考重新命名為 DsSample。

    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();  
      }  
    }  
    

    如果您決定自行建立 Proxy 類別,您必須採取下列額外步驟。 若要編譯範例,請提供已建立的 Proxy 連結庫(sample.dll)和相關 .NET 連結庫。 若要編譯範例的 Visual Basic .NET 版本,儲存在檔案client.vb,請發出下列命令。

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

    若要編譯範例的 C# 版本,儲存在檔案client.cs,請發出下列命令。

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

另請參閱