Partilhar via


Consumir um DataSet de um serviço Web XML

O DataSet foi arquitetado com um design desconectado, em parte para facilitar o transporte conveniente de dados através da Internet. O DataSet é "serializável" na medida em que pode ser especificado como uma entrada ou saída de XML Web Services sem qualquer codificação adicional necessária para transmitir o conteúdo do DataSet de um XML Web Services para um cliente e vice-versa. O DataSet é implicitamente convertido em um fluxo XML usando o formato DiffGram, enviado pela rede e, em seguida, reconstruído a partir do fluxo XML como um DataSet na extremidade recetora. Isso oferece um método simples e flexível para transmitir e retornar dados relacionais usando XML Web Services. Para obter mais informações sobre o formato DiffGram, consulte DiffGrams.

O exemplo a seguir mostra como criar um XML Web Service e um cliente que usam o DataSet para transportar dados relacionais (incluindo dados modificados) e resolver quaisquer atualizações de volta para a fonte de dados original.

Nota

A transmissão DataSet ou DataTable instâncias como parte de chamadas de XML Web Services não é segura se a entrada não for confiável. Para obter mais informações, consulte Diretrizes de segurança DataSet e DataTable. Também recomendamos que você sempre considere as implicações de segurança ao criar um XML Web Services. Para obter informações sobre como proteger um XML Web Services, consulte Protegendo XML Web Services criados usando ASP.NET.

Criar um serviço Web XML

  1. Crie o XML Web Service.

    No exemplo, é criado um XML Web Service que retorna dados, neste caso uma lista de clientes do banco de dados Northwind , e recebe um DataSet com atualizações para os dados, que o XML Web Service resolve de volta para a fonte de dados original.

    O XML Web Service expõe dois métodos: GetCustomers, para retornar a lista de clientes, e UpdateCustomers, para resolver atualizações de volta para a fonte de dados. O XML Web Service é armazenado em um arquivo no servidor Web chamado DataSetSample.asmx. O código a seguir descreve o conteúdo de 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;  
      }  
    }  
    

    Em um cenário típico, o método UpdateCustomers seria escrito para capturar violações de simultaneidade otimistas. Para simplificar, o exemplo não inclui isso. Para obter mais informações sobre simultaneidade otimista, consulte Simultaneidade otimista.

  2. Crie um proxy de serviço Web XML.

    Os clientes do XML Web Service exigem um proxy SOAP para consumir os métodos expostos. Você pode fazer com que o Visual Studio gere esse proxy para você. Ao definir uma referência da Web para um serviço Web existente de dentro do Visual Studio, todo o comportamento descrito nesta etapa ocorre de forma transparente. Se você quiser criar a classe proxy por conta própria, continue com esta discussão. Na maioria das circunstâncias, no entanto, usar o Visual Studio para criar a classe proxy para o aplicativo cliente é suficiente.

    Um proxy pode ser criado usando a Web Services Description Language Tool. Por exemplo, se o XML Web Service for exposto na URL http://myserver/data/DataSetSample.asmx, emita um comando como o seguinte para criar um proxy do Visual Basic .NET com um namespace de WebData.DSSample e armazená-lo no sample.vb de arquivos.

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

    Para criar um proxy C# no sample.cs de arquivos, execute o seguinte comando.

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

    O proxy pode então ser compilado como uma biblioteca e importado para o cliente XML Web Services. Para compilar o código proxy do Visual Basic .NET armazenado no sample.vb como sample.dll, emita o seguinte comando.

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

    Para compilar o código proxy C# armazenado no sample.cs como sample.dll, execute o seguinte comando.

    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. Crie um cliente de serviço Web XML.

    Se você quiser que o Visual Studio gere a classe de proxy de serviço Web para você, basta criar o projeto cliente e, na janela Gerenciador de Soluções, clique com o botão direito do mouse no projeto e selecione Adicionar>Referência de Serviço. Na caixa de diálogo Adicionar Referência de Serviço, selecione Avançado e, em seguida, selecione Adicionar Referência da Web. Selecione o serviço Web na lista de serviços Web disponíveis (isso pode exigir o fornecimento do endereço do ponto de extremidade do serviço Web se o serviço Web não estiver disponível na solução atual ou no computador atual). Se você mesmo criar o proxy do XML Web Services (conforme descrito na etapa anterior), poderá importá-lo para o código do cliente e consumir os métodos do XML Web Services.

    O código de exemplo a seguir importa a biblioteca de proxy, chama GetCustomers para obter uma lista de clientes, adiciona um novo cliente e retorna um DataSet com as atualizações para UpdateCustomers.

    O exemplo passa o DataSet retornado por DataSet.GetChanges para UpdateCustomers porque apenas linhas modificadas precisam ser passadas para UpdateCustomers. UpdateCustomers retorna o DataSet resolvido, que você pode mesclar no DataSet existente para incorporar as alterações resolvidas e quaisquer informações de erro de linha da atualização. O código a seguir pressupõe que você tenha usado o Visual Studio para criar a referência da Web e que você tenha renomeado a referência da Web para DsSample na caixa de diálogo Adicionar referência da Web.

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

    Se você decidir criar a classe proxy por conta própria, deverá executar as seguintes etapas extras. Para compilar o exemplo, forneça a biblioteca de proxy que foi criada (sample.dll) e as bibliotecas .NET relacionadas. Para compilar a versão do Visual Basic .NET do exemplo, armazenada no arquivo client.vb, emita o seguinte comando.

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

    Para compilar a versão em C# do exemplo, armazenada no client.cs de arquivos, execute o seguinte comando.

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

Consulte também