ASP. NET 2008 - Criando Web Services II


Os Web services surgiram com uma promessa de revolucionar a forma como a informação é compartilhada. Eles fornecem uma forma padrão e universal de intercambiar informações de uma maneira simples; são componentes que permitem às aplicações enviar e receber dados em formato XML.

Os Web services podem ser vistos como aplicações modulares que podem ser descritas, publicadas, localizadas e invocadas sobre o protocolo padrão da Internet usando mensagens XML padronizadas; as aplicações usam como base o XML SOAP para troca de informação onde o ambiente de distribuição das aplicações postadas na web são descritas através do WSDL - Web Service Description Language e são registrados com um registro de serviço privado ou público usando o padrão UDDI, tal como http://uddi.microsoft.com ou http://uddi.ibm.com.

SOAP (originado do acrônimo inglês Simple Object Access Protocol) é um protocolo para troca de informações estruturadas em uma plataforma descentralizada e distribuída, utilizando tecnologias baseadas em XML. Sua especificação define um framework que provê maneiras para se construir mensagens que podem trafegar através de diversos protocolos e que foi especificado de forma a ser independente de qualquer modelo de programação ou outra implementação específica. Por não se tratar de um protocolo de acesso a objetos, o acrônimo não é mais utilizado.

Geralmente servidores SOAP são implementados utilizando-se servidores HTTP, embora isto não seja uma restrição para funcionamento do protocolo. As mensagens SOAP são documentos XML que aderem a uma especificação fornecida pelo órgão W3C.

O primeiro esforço do desenvolvimento do SOAP foi implementar RPCs sobre XML.(http://pt.wikipedia.org/wiki/SOAP)

Os Web Services usam basicamente o protocolo HTTP (Hypertext Transfer Protocol) e SOAP para tornar informações disponíveis na web. Eles expõem objetos de negócio para chamadas SOAP atraves de HTTP e executam chamadas de funções remotas. Os consumidores dos web services estão aptos a invocar as chamadas de métodos no objetos remotos usando SOAP e HTTP.

O Web Services Definition Language (WSDL) é uma linguagem baseada em XML utilizada para descrever Web Services. Trata-se de um documento escrito em XML que além de descrever o serviço, especifica como acessá-lo e quais as operações ou métodos disponíveis.

Foi submetido ao W3C por Ariba, IBM e Microsoft em março de 2001 sendo que seu primeiro rascunho foi disponibilizado em julho de 2002.

 

Nota: Web Service Enhancements (WSE) 2.0 é um add-on para o Visual Studio que simplifica o desenvolvimento e a distribuição de web services seguros. Para detalhes veja: http://msdn.microsoft.com/webservices/webservices/building/wse/default.aspx.

Como eu já abordei o assunto em dois artigos anteriores (veja as referências) vou me ater a um enfoque mais prático mostrando como criar e usar os web services levando em conta alguns cenários usando o Visual Web Developer 2008 Express Edition.(VWD2008)

Inicie o VWD2008 e crie um novo web site atraves do menu File -> New Web Site selecionando o template ASP .NET Web Service e informando o nome WebService1;

Na janela Solution Explorer você deverá ver uma pasta App_Code contendo o arquivo code-behind para o web service , uma pasta App_Data e os arquivos Service.asmx e web.config.

No ASP .NET um web service é constituido de um arquivo .asmx e uma classe code-behind que fornece a funcionalidade requerida. O conteúdo do arquivo .asmx é apenas uma linha que contém a diretiva WebService idêntica a uma diretiva @Page usada em um arquivo .aspx . No nosso exemplo temos:

<%@ WebService Language="vb" CodeBehind="~/App_Code/Service.vb" Class="Service" %>

O arquivo code-behind Service.vb da pasta App_Code é uma classe que herda de System.Web.Services.WebService:

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols

' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
' <System.Web.Script.Services.ScriptService()> _
<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class Service
     Inherits System.Web.Services.WebService

    <WebMethod()> _
    Public Function HelloWorld() As String
        Return "Hello World"
    End Function

End Class

Observe que temos uma atributo WebService na definição da classe que permite definir o namespace para o web service. Por padrão o namespace é definido para http://tempuri.org/ mas você pode alterar para uma URI representando sua empresa.

<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

Além disso existe também um atributo WebServiceBinding que indica que o web service esta em conformidade com a especificação WS-I BP 1.1 - Web Services Interoperability Basic Profile specification.(veja detalhes em http://www.ws-i.org.)

Até este momento, embora o web service criado seja perfeitamente funcional, ele é não faz nada de realmente útil.

Para incluir uma funcionalidade ao web service devemos criar métodos como fazermos em uma classe comum; a exceção é que precedemos cada definição de método com o atributo WebMethod que informa que o método deve ser exposto como um web service.

Neste nosso primeiro exemplo eu vou criar um método para acessar um banco de dados e retornar informações de uma tabela. Vou usar o banco de dados Northwind.mdf e acessar a tabela Products, isso será feito através do método getProdutos.

Obs: Voce pode obter o banco de dados de exemplo Northwind.mdf neste link: Northwind

No arquivo service.vb vamos substituir o método HelloWorld pelo método getProdutos() conforme o código abaixo:

Primeiro declare os namespaces usados para acessar o SQL Server e pode acessar a string de conexão no arquivo web.config:

Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient

Em sguida defina o seguinte código para o método getProdutos():

    <WebMethod()> _
  Function getProdutos(ByVal produtos As Integer) As DataSet
        'define as variáveis objetos usadas 
        Dim conexaoBD As SqlConnection = Nothing
        Dim da As SqlDataAdapter = Nothing
        Dim ds As DataSet = Nothing
        Dim cmd As String
        Dim sql As String

        Try
            'Obtem a string de conexão do web.config 
            'abre a conexao com o banco de dados
            cmd = ConfigurationManager.ConnectionStrings("conexaoNorthwind").ConnectionString
            conexaoBD = New SqlConnection(cmd)
            conexaoBD.Open()

            'monta a instrução SQL para obter os dados da tabela Products
            sql = "SELECT Top " & produtos.ToString() & " " & _
                    "ProductID, ProductName, UnitPrice " & _
                    "FROM Products " & _
                    "ORDER BY ProductName"

            'cria um novo dataset 
            'preenche o dataset com produtos
            ds = New DataSet
            da = New SqlDataAdapter(sql, conexaoBD)
            da.Fill(ds)

            'retorna a lista de produtos
            Return (ds)

        Finally
            'libera objetos da memória
            If (Not IsNothing(conexaoBD)) Then
                conexaoBD.Close()
            End If
        End Try
    End Function

A string de conexão deverá estar definida no arquivo web.config conforme o código abaixo:

Obs: Eu estou usando o SQL Server 2005 Express Edition na minha máquina local.


     ....
    <appSettings/>
    <connectionStrings>
        <add name="conexaoNorthwind" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Northwind;Integrated Security=True" _
 providerName="System.Data.SqlClient"/>
    </connectionStrings>
     ....

O método getProdutos() recebe como parâmetro o número de produtos e consulta o banco de dados Northwind retornando uma lista de produtos em um dataset. Toda a infraestrutura de suporte ao web service como a criação do XML e do SOAP usado para tranferir os dados para o cliente é feito de forma transparente pela plataforma .NET.

Neste momento já podemos testar o web service no VWD2008 rodando o projeto. Ao fazer isso será aberta uma página ASP .NET exibindo uma relação com todos os métodos expostos pelo web service. No nosso caso temos apenas o método getProdutos:

Ao clicar no método getProdutos() será exibida outra página, veja abaixo, onde você deve informar um valor que representa o parâmetro produtos e especifica a quantidade de livros sobre o qual desejamos obter informações.

Após fazer isso e clicar no botão invoke será executado o método do webservice.

A ASP .NET gera uma requisição Get HTTP e submete-a ao web service. O web service responde com um reponse Http contendo os dados requisitados. No nosso exemplo será retornado o XML (mostrado na figura abaixo) partir do web service exibindo os campos ProductID, ProductName, UnitPrice para a quantidade de produtos especificada no parâmetro produtos.

O arquivo XML completo gerado é exibido a seguir:

<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://tempuri.org/">
  <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
      <xs:complexType>
        <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element name="Table">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="ProductID" type="xs:int" minOccurs="0" />
                <xs:element name="ProductName" type="xs:string" minOccurs="0" />
                <xs:element name="UnitPrice" type="xs:decimal" minOccurs="0" />
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:choice>
      </xs:complexType>
    </xs:element>
  </xs:schema>
  <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <NewDataSet xmlns="">
      <Table diffgr:id="Table1" msdata:rowOrder="0">
        <ProductID>17</ProductID>
        <ProductName>Alice Mutton</ProductName>
        <UnitPrice>39.0000</UnitPrice>
      </Table>
      <Table diffgr:id="Table2" msdata:rowOrder="1">
        <ProductID>3</ProductID>
        <ProductName>Aniseed Syrup</ProductName>
        <UnitPrice>10.0000</UnitPrice>
      </Table>
      <Table diffgr:id="Table3" msdata:rowOrder="2">
        <ProductID>40</ProductID>
        <ProductName>Boston Crab Meat</ProductName>
        <UnitPrice>18.4000</UnitPrice>
      </Table>
      <Table diffgr:id="Table4" msdata:rowOrder="3">
        <ProductID>60</ProductID>
        <ProductName>Camembert Pierrot</ProductName>
        <UnitPrice>34.0000</UnitPrice>
      </Table>
      <Table diffgr:id="Table5" msdata:rowOrder="4">
        <ProductID>18</ProductID>
        <ProductName>Carnarvon Tigers</ProductName>
        <UnitPrice>62.5000</UnitPrice>
      </Table>
    </NewDataSet>
  </diffgr:diffgram>
</DataSet>

Sejamos sinceros, é muito fácil criar web services na plataforma .NET. É claro que existem muitos outros detalhes que não abordamos neste artigo mas aguarde que irei mostrar outros cenários na criação de web services.

Pegue o projeto completo aqui : WebService1.zip

Acompanhe o artigo onde eu mostro como consumir um web service: VB. NET - Consumindo um Web Service

Eu sei é apenas ASP .NET, mas eu gosto...

Referências:


José Carlos Macoratti