Consumir um Conjunto de Dados de um serviço Web XML

O DataSet foi projetado com um design desconectado, em parte para facilitar o transporte prático dos dados pela Internet. O Conjunto de Dados é "serializável", pois pode ser especificado como entrada ou saída de serviços Web XML, sem a necessidade de codificação adicional para transmitir e retornar o conteúdo do Conjunto de Dados de um serviço Web XML de um cliente. O Conjunto de Dados é convertido implicitamente em um fluxo XML, usando o formato DiffGram enviado pela rede e reconstruído pelo fluxo XML como Conjunto de Dados na extremidade de recebimento. Isso fornece um método simples e flexível para transmitir e retornar dados relacionais, usando os serviços Web XML. Para obter mais informações sobre o formato DiffGram, confira DiffGrams.

O exemplo a seguir mostra como criar um serviço Web XML e um cliente que usam o Conjunto de Dados para transportar dados relacionais (incluindo os dados modificados) e resolver as atualizações novamente para a fonte de dados original.

Observação

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

Criar um serviço Web XML

  1. Crie o serviço Web XML.

    No exemplo, é criado um serviço Web XML que retorna dados, nesse caso, uma lista de clientes do banco de dados Northwind, e recebe um Conjunto de Dados com atualizações para os dados, que o serviço Web XML resolve novamente para a fonte de dados original.

    O serviço Web XML expõe dois métodos: GetCustomers, para retornar a lista de clientes, e UpdateCustomers, para resolver as atualizações novamente para a fonte de dados. O serviço Web XML é armazenado em um arquivo no servidor Web chamado DataSetSample.asmx. O código a seguir descreve o conteúdo do 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 é gravado para capturar violações de simultaneidade otimista. Para simplificar, o exemplo não inclui isso. Para obter mais informações sobre simultaneidade otimista, confira Simultaneidade Otimista.

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

    Os clientes do serviço Web XML 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 no 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. No entanto, na maioria das circunstâncias, é suficiente usar o Visual Studio para criar a classe proxy para o aplicativo cliente.

    Um proxy pode ser criado usando a Ferramenta de Linguagem WSDL. Por exemplo, se o serviço Web XML for exposto na URL http://myserver/data/DataSetSample.asmx, execute um comando como o seguinte para criar um proxy do Visual Basic .NET com um namespace de WebData.DSSample e armazene no arquivo sample.vb.

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

    Para criar um proxy do C# no arquivo sample.cs, execute o comando a seguir.

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

    Em seguida, o proxy pode ser compilado como biblioteca e importado para o cliente de serviço Web XML. Para compilar o código proxy do Visual Basic .NET armazenado em sample.vb como sample.dll, execute o comando a seguir.

    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 do C# armazenado em sample.cs como sample.dll, execute o comando a seguir.

    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 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, Adicionar Referência da Web. Selecione o serviço Web na lista de serviços Web disponíveis (isso pode exigir que o endereço do ponto de extremidade do serviço Web seja fornecido, se o serviço Web não estiver disponível na solução atual ou no computador atual). Se você criar o proxy de serviço Web XML por conta própria (conforme descrito na etapa anterior), pode importá-lo para o código do cliente e consumir os métodos de serviço Web XML.

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

    O exemplo passa o Conjunto de Dados retornado pelo DataSet.GetChanges para o UpdateCustomers, pois apenas as linhas modificadas precisam ser passadas para o UpdateCustomers. UpdateCustomers retorna o Conjunto de Dados resolvido, que você pode Mesclar com o Conjunto de Dados existente, para incorporar as alterações resolvidas e as informações de erro de linha da atualização. O código a seguir pressupõe que você usou o Visual Studio para criar a referência da Web e que você renomeou a referência da Web como 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, deve executar as etapas adicionais a seguir. Para compilar o exemplo, forneça a biblioteca de proxy que foi criada (sample.dll) e as bibliotecas do .NET relacionadas. Para compilar a versão do Visual Basic .NET do exemplo, armazenada no client.vb do arquivo, execute o comando a seguir.

    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 do C# do exemplo, armazenada no client.cs do arquivo, execute o comando a seguir.

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

Confira também