Introdução a Web Services com .NET Framework

Os Web Services disponibilizam funcionalidades que podem ser utilizadas por outras aplicações usando um ambiente conectado que pode ser uma rede de computadores ou mesmo a Internet. Um uso típico é a consulta remota a dados.

Acesso a dados remotos com Web Services

É útil sempre que for necessário fazer acesso a dados remotos em um ambiente conectado e até mesmo com plataformas heterogêneas, envolvendo, por exemplo, PCs e dispositivos móveis como Smartphones. Caso se esteja planejando oferecer serviços de software acessados pela Internet, os Web Services também serão um ótimo ponto de partida. Muito utilizado, por exemplo, para prover a interoperabilidade entre empresas através da internet, por exemplo, matrizes e filiais.

O que são Web Services?

Web Service é uma solução utilizada na integração de sistemas e na comunicação entre aplicações diferentes. Com esta tecnologia é possível que novas aplicações possam interagir com aquelas que já existem e que sistemas desenvolvidos em plataformas diferentes sejam compatíveis. Os Web Services são componentes que permitem às aplicações enviar e receber dados em formato XML. Para as empresas, os Web Services podem trazer agilidade para os processos e eficiência na comunicação. Toda e qualquer comunicação entre sistemas passa a ser dinâmica e principalmente segura, pois não há intervenção humana.

O ambiente conectado da Internet fez com que novas aplicações surgissem e uma destas consiste nos Web Services, que permitem que máquinas de plataformas diversas possam facilmente fazer intercâmbio de dados entre si sem que uma precise necessariamente conhecer a outra. Isto tudo é conseguido através de padrões abertos tanto para dados como para protocolos. Os Web Services seguem padrões que podem ser facilmente implementados em qualquer plataforma ou linguagem.

O .NET Framework procura facilitar ainda mais o desenvolvimento de Web Services oferecendo ao programador automatização de tarefas como geração de classes para disponibilização e consumo de Web Services. Também são encontradas facilmente no Framework as ferramentas para referenciar Web Services e assim criar programas que possam interagir com estes de maneira mais simples, além de publicá-los em um servidor com um esforço minimizado.

Existem muitos cenários onde Web Services podem ser empregados. Por exemplo, imagine uma companhia aérea, que oferece vários vôos diários para determinadas localidades. Normalmente, usuários podem consultar estes vôos através do site da empresa, abrindo o endereço no browser. Neste ponto é possível comparar horários, tarifas, disponibilidades etc. Agora imagine que você precisa fazer um programa que consulte automaticamente essas informações, por exemplo, se você está desenvolvendo um aplicativo para uma agência de viagens.

A aplicação deve ser capaz de consultar vários “sites” de companhias aéreas automaticamente, conforme informações fornecidas pelo agente de viagens em um desktop. Veja que a consulta precisa ser feita pelo software, sem intervenção humana, o agente não vai querer abrir página por página de cada companhia. Quando um software precisa obter esse tipo de informação de outro software, a solução ideal não é o uso de um Web Site, que contém marcação HTML para criação de interfaces juntamente com os dados. O ideal é o uso de serviços, que permitem a troca somente dos dados necessários, usando XML ao invés de HTML.

Isso pode ser feito com Web Services. Usando o mesmo exemplo, existem vários outros tipos de aplicações clientes que poderiam tirar proveito deste tipo de serviço. Já existe hoje, por exemplo, aplicativos para iPhone onde o usuário pode acompanhar em tempo real a situação do embarque para o seu vôo (se está atrasado, em embarque etc.). Como uma aplicação rodando em um Smartphone consegue obter essas informações do banco de dados da companhia aérea? Certamente há um Web Service criado no servidor, que pode ter sido escrito em qualquer linguagem sob qualquer plataforma, e nesse caso consumido por outra plataforma completamente diferente.

Serviços como base para novos softwares

A principal motivação para desenvolver e consumir Web Services é a possibilidade de acessar dados de servidores remotos e em alguns casos, usar o processamento destes para executar determinadas tarefas. Atualmente muitas empresas já usam Web Services para disponibilizar serviços e podem ser usados como exemplo:

  • Dados sobre previsão do tempo;
  • Cotações de produtos e bolsas de valores;
  • Agendamento de passagens de avião ou horários;
  • Informações sobre tarifação de serviços de entrega – para informar o preço de um serviço baseando-se na distância a ser percorrida e dados da carga.

Todos estes serviços e muitos outros podem fazer uso de Web Services. Basicamente, se é possível haver troca de dados, estes poderão ser usados. As bases para estes serviços residem em três elementos fundamentais: os documentos XML, o padrão UDDI e o WSDL, como veremos adiante.

XML para intercâmbio de dados

Os Web Services são baseados na troca de mensagens SOAP – Simple Object Access Protocol - usando para transporte o protocolo HTTP. As aplicações, tanto cliente quando servidor, devem ser capazes de lidar com este protocolo e também de lerem os dados no formato XML.

A escolha do formato XML é importante principalmente pelo fato de ser um formato aberto, isto é, não pertence a nenhuma empresa especificamente e o seu padrão é conhecido e mantido pelo W3C que regulamenta padrões da Internet.

Um documento XML é versátil e muito flexível possibilitando várias aplicações, por outro lado, a sua estrutura facilita a compreensão do conteúdo por este transportado por qualquer tipo de programa em qualquer plataforma.

Localizando Web Services

UDDI - Universal Description, Discovery and Integration - é a infraestrutura que padroniza a forma que o Web Service pode ser localizado e desenvolvido. Este é baseado em padrões abertos como o XML. Imagine o UDDI como sendo as “páginas amarelas” de Web Services.

É através deste também que os Web Services podem ser descobertos bastando para isto digitar um endereço no browser como, por exemplo: http://Servidor/diretório/nomedoservico/servico.asmx (ou equivalente).

Descrevendo Web Services

WSDL - Web Services Description Language - é um documento que descreve o Web Service disponibilizado e de uma forma bem resumida, é a interface que é usada para a sua compreensão e utilização. Basicamente os elementos que um WSDL informa são:

  • Dados sobre todos as operações disponibilizadas no servidor;
  • Tipo de dados usados em todas as mensagens no formato XML;
  • Informações sobre protocolos usados na comunicação;
  • Informações sobre os endereços para a localização do Web Service.

O .NET Framework e os Web Services

Ao usar o .NET Framework para criar os Web Services, especialmente baseando-se na plataforma ASP.NET (principalmente representada pela biblioteca System.Web) o desenvolvedor não precisará se preocupar em escrever código para lidar com detalhes internos relativos a transporte, padronização de documentos e requisições ao servidor, ou seja, toda a infraestrutura necessária tanto para disponibilizar e criar os Web Services como para fazer uso destes já é definida automaticamente pelas classes do Framework.

Mais importante ainda, o programador tem facilidades tanto para criar o Web Service e disponibilizar o mesmo para outros aplicativos como para consumir estes Web Services. Se for necessário criar uma aplicação do Framework que utilize Web Services de terceiros, baseado nos padrões utilizados, é bem mais simples desenvolver com as ferramentas disponíveis no Visual Studio 2010.

A criação de uma aplicação para disponibilizar Web Services é feita no Visual Studio como qualquer outro tipo de projeto da plataforma. Para criar uma classe correspondente a um Web Service basta adicionar usando uma caixa de diálogo como já é feito para outros componentes dos projetos do Visual Studio.

Um Web Service deve herdar da classe System.Web.Services.WebService e possuir atributos especiais definidos na sua declaração. A Listagem 1 mostra um exemplo de um tipo de classe destes.

Listagem 1. Exemplo de Web Service


  ...
  public class MeuWebService : System.Web.Services.WebService
  {
      [WebMethod]
      public string OlaMundo()
      {
          return "Olá Mundo!";
      }
  }

Um Web Service tipicamente possui métodos que serão chamados remotamente. Estes são chamados “Web Methods” e para serem implementados no .NET Framework devem ser um método público e marcados com o atributo [WebMethod] como pode ser percebido no exemplo. Outra facilidade possibilitada pelo .NET Framework é a capacidade de gerar o código necessário para acessar o Web Service.

Os Web Methods recebem parâmetros e podem retornar dados basicamente em qualquer formato que seja possível ser serializado em um documento XML e seja suportado também pelo .NET Framework. Logo, é possível usar como parâmetros de entrada e de retorno tipos nativos como: int, decimal, float, DateTime, DataTable e também classes criadas pelo usuário. Aqui serializar refere-se ao fato de transformar uma determinada informação em um formato que possa ser trafegada pela rede, promovendo o intercâmbio entre clientes e servidores.

Disponibilizando com o .NET Framework

Uma questão importante ao desenvolver Web Services é torná-los acessíveis para outros computadores quer em uma rede, quer na Internet. Nos sistemas Microsoft Windows existe um programa responsável por isto chamado Serviço de Informações da Internet ou, Internet Information Services e é mais conhecido pela sigla IIS.

Este programa, originalmente disponível nas versões para servidor e atualmente também em algumas versões para desktop, provê toda a infraestrutura necessária para que uma aplicação Web - seja um Web Service, uma aplicação ASP ou ASP.NET - possa funcionar e prover sua funcionalidade. É acessada através do Painel de Controle e Ferramentas Administrativas e a sua tela principal pode ser conferida na Figura 1.

Tela principal do gerenciador do IIS
Figura 1. Tela principal do gerenciador do IIS

Esta tela corresponde ao IIS na versão 7 que é distribuída junto com o Windows Seven Ultimate Edition. Algumas funcionalidades são acrescentadas ou removidas conforme o conjunto de software instalado no sistema e com certeza, versões desta ferramenta para o servidor são bem diferentes com muito mais opções.

Para poder publicar um Web Service usando o Windows 7 é necessário que toda a configuração de compartilhamento e acesso na rede e liberação de portas de comunicação no Firewall esteja pronta. Geralmente o Web Service usa a porta 80, mas caso seja necessário, pode se usar qualquer outra.

Como já é padrão nos aplicativos Windows e mesmo em se tratando de servidores, a inclusão de um Web Service pode ser feita a partir de um assistente que será demonstrado a seguir, quando estiver descrevendo a aplicação de exemplo.

A maior parte dos sites e aplicações gerenciados pelo IIS ficam em uma pasta especial normalmente localizada no endereço “c:\inetpub\wwwroot”, mas como se pode esperar, é possível também usar outras pastas e configurá-las no IIS.

Normalmente o IIS detecta a versão correta do .NET Framework em que a aplicação foi feita, mas oferece recursos para se fazer ajustes neste e em outros aspectos da mesma.

Para detectar se um computador possui o IIS instalado, se deve verificar os componentes do Windows como na Figura 2, que mostra o IIS instalado.

Gerenciamento de módulos do Windows 7
Figura 2. Gerenciamento de módulos do Windows 7

Normalmente o computador no qual se vai instalar um Web Service é um servidor para o qual o processo de publicação consiste basicamente em copiar os arquivos necessários para uma pasta compartilhada e dificilmente o programador terá acesso ao sistema.

Se desejar saber se o computador remoto possui o IIS instalado, basta abrir o browser e digitar o endereço IP correspondente ou o nome do computador. Neste caso, se o computador estiver configurado para aceitar conexões externas e o IIS instalado, uma página como a da Figura 3 será exibida, se a versão do IIS for a 7 (que é distribuída com a versão 2008 do Windows Server e o Windows 7).

Browser mostrando que o IIS está instalado e
ativo
Figura 3. Browser mostrando que o IIS está instalado e ativo

Nota: o IIS possui um site dedicado a ele com documentação, tutoriais e mais informações sobre esta ferramenta. Na seção de links deste artigo foi disponibilizado o endereço que deverá ser consultado para mais detalhes desta ferramenta da Microsoft.

Para publicar o Web Service no IIS, se o programador estiver usando o Visual Studio, basta executar um assistente dentro do próprio IDE que faz a cópia para o local desejado quer seja em um servidor remoto da Web, em uma pasta compartilhada da rede ou diretamente para uma aplicação do IIS configurada no computador local. Este processo também será demonstrado na aplicação prática.

WCF e além

Os Web Services como descritos estão sendo usados desde 2001 e durante este tempo, como se pode esperar, houve uma considerável evolução no desenvolvimento destes.

O passo mais importante para as plataformas da Microsoft foi a introdução das aplicações Windows Communication Foundation (WCF) a partir do Framework 3.0 e com constantes aperfeiçoamentos.

Este tipo de aplicação mantém compatibilidade com os Web Services clássicos e promove a integração entre diferentes tipos de tecnologia.

Como vantagem reside o fato de oferecer maior confiabilidade e segurança, requerer menos alterações no código para implementar modelos de segurança (isto pode ser feito facilmente com alterações em arquivos de configuração) e também um registro mais completo e integrado com log de eventos ocorridos na aplicação.

Um exemplo de Web Service

Vários tipos de aplicações podem ser criados com os Web Services. Para demonstrar, desenvolvi um programa que é usado para consultar dados de publicações em um banco de dados. O Web Service implementa toda a lógica por trás da consulta ao banco e disponibiliza dois serviços: um para consultar os dados a partir de uma consulta enviada, outro faz a inclusão no banco de dados de registros de publicação enviados pelo usuário.

Uma questão importante ao disponibilizar serviços como este é limitar o acesso apenas para usuários autorizados, afinal, trata-se de recursos de processamento disponíveis publicamente na Internet e dependendo da natureza do serviço é importante que apenas usuários autorizados façam uso. A maneira que a autenticação foi implementada é através de um cadastro contendo um endereço de e-mail (geralmente único) e o nome do usuário. Em cada serviço o usuário deve enviar seu endereço de e-mail para verificação no banco. Somente endereços cadastrados terão o retorno das operações.

A aplicação que irá consumir o Web Service é do tipo Windows Forms e vai ter um formulário onde o usuário pode executar as duas operações informando também o seu e-mail. A Figura 4 demonstra a tela inicial onde se observa o campo para o e-mail e a aba para fazer a consulta com alguns dados retornados. A outra aba serve para cadastramento dos dados e pode ser conferida na Figura 5. Ao digitar o conteúdo que se deseja cadastrar e clicar no botão “OK” o programa pede uma confirmação. Depois de confirmado, os dados são enviados para o Web Service e caso tudo tenha corrido certo, uma mensagem é dada para o usuário.

Tela da aplicação executando a consulta
Figura 4. Tela da aplicação executando a consulta
Aplicação incluindo uma publicação
Figura 5. Aplicação incluindo uma publicação

Estrutura do banco de dados

O banco de dados para o Web Service foi chamado de “Publica” e foi disponibilizado o script para sua geração nos downloads relacionados com este artigo. A primeira tabela armazena os dados da publicação e sua estrutura está demonstrada na Tabela 1. Os dados dos usuários são armazenados na tabela “Usuario” que é exibida na Tabela 2.

Campo

Tipo (Tamanho máximo)

Id

int

Titulo

varchar(50)

Autores

text

PalavrasChave

varchar(50)

Data

date

Publicacao

varchar(50)

Editor

varchar(50)

EnderecoEletronico

varchar(255)

Tabela 1. Estrutura da tabela “Publicacao”

Campo

Tipo (Tamanho máximo)

Email

varchar(60)

Nome

varchar(50)

Tabela 2. Estrutura da tabela “Usuario”

Para o banco de dados eu optei pelo SQL Server 2008 R2 Express mas, qualquer banco de dados suportado pelo .NET Framework pode ser usado.

Criando o projeto do Web Service no Visual Studio

A criação de um projeto de Web Services no Visual Studio é bem simplificada e segue os passos já conhecidos para criação de qualquer projeto. A Figura 6 mostra alguns detalhes que devem ser observados na janela para criação do projeto.

Detalhes da criação do projeto de Web Service
Figura 6. Detalhes da criação do projeto de Web Service

Com o projeto criado, o Visual Studio automaticamente gera todo um conteúdo já voltado para este tipo de aplicação incluindo pastas para armazenamento de dados e um arquivo de configuração Web.Config no mesmo formato do que é usado para uma aplicação ASP.NET.

Os Web Services utilizam toda a infraestrutura já oferecida pelo ASP.NET, os mesmos utilizados em aplicações Web tradicionais, incluindo os mais diversos serviços, como por exemplo cache, configuração, segurança etc.

A classe do Web Service

Os Web Services são criados como uma classe dentro do projeto. Os passos para adicionar são os mesmos usados para adicionar uma classe ou formulário em um projeto, ou seja, basta clicar de direita sobre a Solution Explorer, escolher Add > New Item > Web > Web Service. Quando este serviço é criado, o Visual Studio automaticamente gera todo o código necessário para que a classe esteja disponibilizada como um Web Service (o código gerado para o exemplo é basicamente igual ao código já apresentado na Listagem 1).

O que faz a classe ser usada como um Web Service são os atributos que estão colocados acima da sua declaração, além do fato de estar relacionada com um arquivo ASMX e esta derivar de System.Web.Services.WebService.

Um primeiro WebMethod chamado HelloWorld já é inserido como demonstração. O atributo [WebMethod] colocado acima do método faz com que este esteja visível via browser, como veremos mais à frente.

O arquivo Web.Config

O Web Service de exemplo conecta-se com um banco de dados SQL Server para retornar dados e fazer inclusões. A configuração da conexão com o banco pode ser feita no arquivo Web.Config que é o mesmo que é usado em aplicações ASP.NET. No meu exemplo, a string de conexão ficou como a Listagem 1 demonstra.

Listagem 1. String de conexão com o banco


   18   <connectionStrings>
   19     <add name="padrao" connectionString="Data source=.\SqlExpress;
   20          Initial Catalog=Publica; 
   21          User Id=webservice_publicacao;
   22          Password=publicacao1"/>
   23   </connectionStrings>

Lembrando de que esta string precisa ser alterada conforme cada caso principalmente no tocante ao servidor usado (Data source) e os dados de autenticação do usuário.

Infraestrutura para consultar os dados

No projeto optei por criar uma classe dedicada em fazer as consultas ao banco. Esta classe retorna um objeto DataTable para as consultas feitas, configura parâmetros de consulta, verifica a string de conexão com os dados e executa consultas de atualização no banco. Separando desta forma a tarefa de consulta ao banco do Web Service pode se reaproveitar mais o código.

A classe foi criada com o nome “Dados” e pode ser conferida na Listagem 2. O primeiro método que ela disponibiliza retorna uma instância da classe DataTable para uma consulta informada. A Listagem 3 descreve este método.

O método RetornarTabela precisa receber uma string contendo a instrução SQL que será executada. O segundo parâmetro é um dicionário (do namespace System.Collections.Generic) contendo os parâmetros para a consulta SQL e o último parâmetro é uma variável para armazenar eventuais mensagens de erro que possam ter ocorrido.

Para preencher um objeto DataTable é necessária uma instância de SqlDataAdapter. Este objeto é inicializado dentro de um bloco “using” a partir da linha 19.

Na linha 21, o objeto “SelectCommand” recebe o comando SQL (linha 23) e um objeto SqlConnection (linha 24). Observe nesta linha que através da classe ConfigurationManager, que requer System.Configuration, é lida a string de conexão do arquivo Web.Config.

A partir da linha 28 é iniciado um bloco “try...catch” para poder capturar eventuais erros que ocorrerem.

Como na instrução SQL serão informados parâmetros de consulta para a cláusula WHERE, na linha 30 é feita uma chamada para o método ConfigurarParametros (definido mais à frente) para o envio correto dos parâmetros, conforme passados pelos argumentos de chamada do método.

Novamente é iniciado um bloco “using” para criar uma instância do objeto DataTable que vai receber os dados e dentro deste bloco a consulta é feita enviando os dados da tabela. Observe que para criar o objeto DataTable foi dado um nome para ser usado com a mesma.

Como a tabela será transformada em um documento XML pelo Web Service, sempre que um objeto deste tipo for retornado pelo Web Service deve ser criado com um nome definido, caso contrário, ao executar o código, uma Exception será lançada.

Os blocos “using” que foram usados duas vezes neste método garantem que o objeto seja corretamente removido da memória quando não estiver sendo mais usado. Isto é feito porque ao final do bloco, o método Dispose() será chamado. Este bloco só pode ser usado com classes que implementem a interface IDisposable. Em um ambiente onde nunca se sabe o número de usuários que está acessando a aplicação – logo, sem controle do número de vezes simultâneas que um mesmo processo será executado – é muito importante tratar deste aspecto da programação.

Listagem 2. Classe para consultar os dados


   7 namespace WSPublica
   8 {
   9   /// <summary>
   10   /// Classe que manipula dados
   11   /// </summary>
   12   public class Dados
   13   {

Listagem 3. Método retornando uma tabela com os dados


   14     //Retorna uma tabela preenchida com os dados
   15     public static DataTable RetornarTabela(string SQL,
   16       Dictionary<string, object> parametros,
   17       out string mensagem)
   18     {
   19       using (SqlDataAdapter daConsulta = new SqlDataAdapter
   20       {
   21         SelectCommand = new SqlCommand
   22         {
   23           CommandText = SQL,
   24           Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["padrao"].ToString())
   25         }
   26       })
   27       {
   28         try
   29         {
   30           ConfigurarParametros(daConsulta.SelectCommand, parametros);
   31 
   32           using (DataTable dtRet = new DataTable("Publicacao"))
   33           {
   34             daConsulta.Fill(dtRet);
   35             mensagem = string.Empty;
   36             return dtRet;
   37           }
   38         }
   39         catch (Exception ex)
   40         {
   41           mensagem = string.Format("Não foi possível executar a consulta.\n{0}",
   42             ex.Message);
   43         }
   44         finally
   45         {
   46           if (daConsulta.SelectCommand.Connection.State == ConnectionState.Open)
   47           {
   48             daConsulta.SelectCommand.Connection.Close();
   49           }
   50         }  
   51          }
   52          return new DataTable("default");
Uma segunda função da classe que trabalha com os bancos de dados é executar instruções SQL de atualização de dados (INSERT, DELETE, UPDATE). Para isto o método da Listagem 4 foi definido. Assim como o método RetornarTabela, o método ExecutarSQL recebe uma string contendo um comando SQL e um Dictionary<> com os parâmetros nos seus argumentos e mais uma variável de retorno para armazenar eventuais mensagens de erro. A linha 60 cria uma instância da classe SqlCommand que é usada para este tipo de operação no banco. Na linha 62 a conexão com o banco é definida e em seguida é passado o comando SQL que será usado. Novamente foi definido um bloco “try...catch” na linha 68 sendo que primeiramente se definem os parâmetros do comando, abre-se a conexão com o banco e faz a execução do comando. Havendo sucesso na operação é necessário inicializar a variável de retorno que recebe as mensagens de erro, o que neste caso não ocorreu. Finalizando o método, foi definido o bloco “catch” (linha 73) para tratamento de erros e o bloco “finally” (linha 78) que fecha a conexão com o banco de dados. A linha 84 faz o retorno da operação usando como critério a existência ou não de mensagem de erro, o que indicará se houve sucesso ou falha na operação.

Listagem 4. Método para executar instruções SQL de atualização


   56     //Executa um comando SQL
   57     internal static bool ExecutarSQL(string comandoSql, 
   58       Dictionary<string, object> parametros, out string mensagem)
   59     {
   60       using (SqlCommand SqlCmd = new SqlCommand
   61       {
   62         Connection = new SqlConnection(ConfigurationManager.ConnectionStrings["padrao"].ToString()),
   63         CommandText = comandoSql
   64       })
   65       {
   66         try
   67         {
   68           ConfigurarParametros(SqlCmd, parametros);
   69           SqlCmd.Connection.Open();
   70           SqlCmd.ExecuteNonQuery();
   71           mensagem = string.Empty;
   72         }
   73         catch (Exception ex)
   74         {
   75           mensagem = string.Format("Não foi possível executar o comando SQL.\n{0}",
   76             ex.Message);
   77         }
   78         finally
   79         {
   80           SqlCmd.Connection.Close();
   81         }
   82       }
   83 
   84       return string.IsNullOrEmpty(mensagem);
   85     }

Os dois métodos descritos fazem a configuração dos parâmetros da instrução SQL usando o método ConfigurarParametros que é definido como na Listagem 5.

Como argumentos o método recebe um SqlCommand para ser configurado e o Dictionary<> contendo o conjunto com o nome e o valor do parâmetro.

O loop da linha 91 percorre todas as chaves e adiciona ao comando definido em “SqlCmd”.

Listagem 5. Método para configuração de parâmetros


   87     //Configuração dos parâmetros SQL
   88     private static void ConfigurarParametros(SqlCommand SqlCmd, 
   89       Dictionary<string, object> parametros)
   90     {
   91       foreach (string key in parametros.Keys)
   92       {
   93         SqlCmd.Parameters.AddWithValue(key, parametros[key]);
   94       }
   95       }

Definindo o Web Service

O Web Service possui dois métodos visíveis para as aplicações. O primeiro, recebe uma consulta e retorna uma tabela preenchida com os dados encontrados. Este método pode ser conferido na Listagem 6.

Os argumentos de entrada são o e-mail do usuário que será usado para autenticá-lo no serviço, uma string contendo a consulta a ser executada e uma variável de retorno para retorno de alguma mensagem de erro.

Como foi definida uma classe para manipulação dos dados, ao WebMethod resta apenas as tarefas de verificar se o usuário está autorizado a executar a consulta através de uma chamada para o método AutenticarUsuario (que será descrito à frente). Feita a verificação, é definida a instrução SQL que recupera os campos necessários para retorno e o filtro a ser aplicado a partir da linha 45.

Neste exemplo, a consulta será feita comparando vários campos da tabela através da instrução LIKE.

No bloco da linha 60 é criado o Dictionary<> com o parâmetro para ser usado na instrução observando que é feita uma formatação do valor para poder ser usado na instrução.

Por fim, a linha 65 faz uma chamada para o método que executa a consulta retornando a tabela que for gerada.

Listagem 6. Método de retorno da tabela contendo dados da consulta


   36     //Executa a consulta
   37     [WebMethod]
   38     public DataTable Consultar(string usuario, string consulta, out string mensagem)
   39     {
   40       if (!AutenticarUsuario(usuario, out mensagem))
   41       {
   42         return null;
   43       }
   44 
   45       string ComandoSql = @"
   46         SELECT  Titulo,
   47               Autores,
   48               PalavrasChave,
   49               Data,
   50               Publicacao,
   51               Editor,
   52               EnderecoEletronico
   53         FROM Publicacao
   54         WHERE Titulo LIKE @Parametro
   55             OR Autores LIKE @Parametro
   56             OR PalavrasChave LIKE @Parametro
   57             OR Publicacao LIKE @Parametro
   58             OR Editor LIKE @Parametro";
   59 
   60       Dictionary<string, object> parametros = new Dictionary<string, object> 
   61       {
   62           { "@Parametro" , string.Format("%{0}%", consulta) }
   63       };
   64 
   65       return Dados.RetornarTabela(ComandoSql, parametros, out mensagem);
   66     }

A inclusão do registro, da mesma forma, recebe os parâmetros, autentica o usuário, configura a consulta e chama o método da classe de manipulação de dados e sua implementação foi feita conforme o método descrito na Listagem 7.

O primeiro parâmetro do método contém os dados para inclusão na tabela. Como se pode observar, é usada uma classe já que são vários campos a serem passados. Desta forma simplifica-se a assinatura do método e sua implementação.

O método faz a autenticação do usuário como demonstrado anteriormente (linha 72) e define a instrução SQL na linha 74.

Também são configurados os parâmetros para serem usados a partir da linha 80. Como o Web Service não sabe a origem dos dados, é feito um tratamento do tamanho dos dados do tipo string para que não ultrapassem o tamanho máximo definido na tabela. Para isso, foi usado o recurso de métodos de extensão onde é passado o tamanho máximo do campo.

Caso a string ultrapasse este tamanho, a mesma é truncada até o valor permitido. O método de extensão será demonstrado à frente.

Na linha 90 é retornado o resultado da operação através de uma chamada ao método ExecutarSQL da classe Dados, vista anteriormente.

Listagem 7. Inclusão de registro


  68 //Inclui uma publicação
  69 [WebMethod]
  70 public bool IncluirPublicacao(DadosPublicacao dados, string usuario, out string mensagem)
  71 {
  72 if (!AutenticarUsuario(usuario, out mensagem)) return false;
  73
  74 string comandoSql = @"
  75 INSERT INTO Publicacao
  76 (Titulo, Autores, PalavrasChave, Data, Publicacao, Editor, EnderecoEletronico)
  77 VALUES
  78 (@Titulo, @Autores, @PalavrasChave, @Data, @Publicacao, @Editor, @EnderecoEletronico)";
  79
  80 Dictionary parametros = new Dictionary {
  81 { "@Titulo", dados.Titulo.AjustarString(50) },
  82 { "@Autores", dados.Autores },
  83 { "@PalavrasChave", dados.PalavrasChave.AjustarString(50) },
  84 { "@Data", dados.Data },
  85 { "@Publicacao", dados.Publicacao.AjustarString(50) },
  86 { "@Editor", dados.Editor.AjustarString(50) },
  87 { "@EnderecoEletronico", dados.EnderecoEletronico.AjustarString(255) }
  88 };
  89
  90 return Dados.ExecutarSQL(comandoSql, parametros, out mensagem);
  91 }

Classes do Web Service são disponibilizadas da mesma forma que os serviços para serem usados pela aplicação que fizer a conexão. Uma observação importante é que a classe seja pública e que a aplicação que estará conectando-se ao Web Service tenha condições de definir um objeto usando a classe.

Nas operações anteriores foi feita a autenticação de usuário. Para isto, o e-mail que é passado nos argumentos precisa ser consultado no banco. A Listagem 8 mostra o método “AutenticarUsuario”. Este método monta uma consulta SQL para consultar o endereço de e-mail na tabela “Usuario” do banco. Havendo registros (linha 106) nenhuma mensagem de erro é configurada e o usuário é autenticado, caso contrário, uma mensagem de erro é configurada para retorno (linha 114).

Listagem 8. Autenticação de usuário


   93     //Faz a autenticação do usuário
   94     private bool AutenticarUsuario(string usuario, out string mensagem)
   95     {
   96       string ComandoSql = @"
   97         SELECT Nome FROM Usuario 
   98         WHERE Email = @Email";
   99 
   100       Dictionary<string, object> parametros =
   101         new Dictionary<string, object> 
   102         {
   103             { "@Email", usuario }
   104         };
   105 
   106       if (Dados.RetornarTabela(ComandoSql, parametros, out mensagem).Rows.Count == 0)
   107       {
   108         if (string.IsNullOrEmpty(mensagem))
   109         {
   110           mensagem = @"Usuário não encontrado.";
   111         }
   112       }
   113 
   114       return string.IsNullOrEmpty(mensagem);
   115     }

Classes auxiliares usadas

No Web Service também foram criadas classes para armazenar os dados da publicação na operação de inclusão. Esta classe pode ser conferida na Listagem 9.

Listagem 9. Classe usada para inclusão de registro


   1 using System;
   2 
   3 namespace WSPublica
   4 {
   5   public class DadosPublicacao
   6   {
   7     public string Titulo { get; set; }
   8     public string Autores { get; set; }
   9     public string PalavrasChave { get; set; }
   10     public DateTime Data { get; set; }
   11     public string Publicacao { get; set; }
   12     public string Editor { get; set; }
   13     public string EnderecoEletronico { get; set; }
   14   }
   15 }

Além desta classe, foi definida uma classe com métodos de extensão (Extension Methods) para truncar o tamanho da string para o tamanho máximo permitido pelo campo no banco de dados (código está disponível no endereço para download).

Os Extension Methods foram incluídos a partir da versão 3.0 do .NET Framework e permitem acrescentar funcionalidades para tipos nativos do Framework ou classes personalizadas sem ser necessário criar um Override (sobreposição) de métodos ou derivar as classes.

Publicando o projeto

Os Web Services precisam ser disponibilizados para acesso externo e a maneira de se fazer isto é através da ferramenta Serviços de Informações da Internet ou Internet Information Services (IIS). No exemplo usou-se a versão 7 desta ferramenta que é instalada junto com o Windows 7. Deve se observar que versões mais básicas deste sistema não possuem esta ferramenta.

O primeiro passo é criar uma aplicação para o Web Service, isto é feito como demonstra a Figura 7. Neste caso, como se tem um executável – o Web Service gera um arquivo DLL – é necessário usar a função “Add Application...” em fez de “Virtual Directory”.

Publicando uma aplicação no IIS
Figura 7. Publicando uma aplicação no IIS

Ao selecionar a opção, o IIS abre uma janela de diálogo onde se deve informar o nome da aplicação e o diretório da mesma dentro do servidor. Na Figura 8 esta tela é demonstrada já com os dados referentes ao projeto de exemplo preenchidos. Feito isto a aplicação está criada e passa a ser mostrada no IIS, porém, nenhum conteúdo ainda foi copiado para a pasta sendo necessário fazer a cópia dos arquivos necessários.

Configurando a aplicação no IIS
Figura 8. Configurando a aplicação no IIS

Publicando o Web Service com o Visual Studio

O Visual Studio possui um assistente de publicação de conteúdo para o IIS incorporado deste as primeiras versões. Para executá-lo, basta clicar sobre o ícone do projeto do Web Service na janela Solution Explorer com o botão direito do mouse e escolher a opção “Publish”. Este assistente possui vários recursos para o envio dos arquivos necessários sendo que é possível fazer o envio remotamente (pela Web) ou localmente.

A Figura 9 mostra a primeira tela deste assistente. Para o projeto de exemplo foi selecionada a opção File System, já que o IIS está localizado no mesmo disco que o projeto. O próximo passo é selecionar o local, onde há duas opções para selecionar o destino, uma escolhendo a pasta do servidor ou, se for o caso, selecionar a aplicação no IIS à qual o projeto se refere.

Assistente de publicação do Visual Studio
Figura 9. Assistente de publicação do Visual Studio

Com estes passos a aplicação já está disponível para ser acessada tanto localmente como externamente. Uma maneira de se fazer testes com os Web Services é acessando-os via browser. Para acessar na mesma máquina onde está publicado deve se digitar, no caso do exemplo do artigo: http://localhost/publicacao/publicacao.asmx. Caso tudo esteja correto, uma página como a da Figura 10 é exibida.

Visualizando o Web Service no browser
Figura 10. Visualizando o Web Service no browser

O projeto cliente Windows Forms

A aplicação que vai utilizar o Web Service é do tipo Windows Forms. A criação do projeto segue os padrões que estão detalhados na Figura 11.

Incluindo um projeto Windows Forms
Figura 11. Incluindo um projeto Windows Forms

O formulário principal precisa disponibilizar um campo para o usuário digitar o e-mail usado na autenticação. Também foram definidas duas abas (usando o controle Tab Control) sendo que uma possui o campo para a consulta, um botão para executar e um controle DataGridView para receber o resultado da consulta. A segunda aba possui os campos e botões para executar o cadastramento de um registro novo (as telas da aplicação já foram apresentadas anteriormente neste artigo).

Definido o design, é necessário configurar o Web Service que será usado pela aplicação. A partir do Framework 3.5 a Microsoft passou a oferecer além dos Web Services aplicações conhecidas como WCF. Para manter uma compatibilidade com os Web Services, os passos para configurar no projeto são descritos a seguir.

A referência a um Web Service é feita na janela Solution Explorer clicando sobre o projeto Windows com o botão direito do mouse e escolhendo a opção Add Service Reference. A primeira janela exibida é a mostra opções básicas para conexão. Esta janela é mais indicada para a conexão com serviços WCF. Como no projeto é preciso conectar com Web Services, é necessário clicar no botão Advanced. Nesta janela várias opções são disponibilizadas, mas a que interessa é representada pelo botão Add Web Reference. Como pode se notar, o código que será gerado, mantém compatibilidade com o Framework 2.0.

A janela que é aberta pode ser conferida na Figura 12. Nesta janela, uma vez digitado o endereço do Web Service (que pode ser local ou remoto), se o mesmo estiver disponível, é mostrada uma página que corresponde àquela mesma que foi usada para testar o Web Service (UDDI) e mostra os WebMethods disponíveis. Para acrescentar a referência e concluir a tarefa deve se dar um nome para a referência no campo Web reference name.

Adicionando referência ao Web Service (passo final)
Figura 12. Adicionando referência ao Web Service (passo final)

Estes passos, embora um pouco longos, simplificam todo o processo de conexão com o Web Service. Ao finalizar a operação o Visual Studio cria uma classe especial, chamada de classe Proxy através da leitura do documento WSDL vinculado com o serviço.

Nota: É comum que os Web Services sejam alterados e novos métodos sejam acrescentados ou, novos argumentos sejam suportados. Nestes casos, para a aplicação que usa o Web Service, é necessário fazer uma atualização. Isto pode ser feito no Visual Studio clicando-se sobre o ícone correspondente na pasta Web References com o botão direito do mouse e escolhendo a opção Update Web Reference.

Consultando com o Web Service

A primeira aba da aplicação Windows faz a consulta dos dados. O método que responde ao clique do mouse sobre o botão Consultar está descrito na Listagem 10. O método cria uma instância da classe correspondente ao Web Service que foi referenciado na linha 16.

Um aspecto importante é que o endereço do Web Service normalmente é diferente em tempo de projeto e em ambiente de produção. A linha 17 mostra como deve ser passado para o objeto o endereço correto. Considere manter este e os demais endereços no arquivo de configuração da aplicação Windows.

Na linha 19 uma variável recebe o resultado da consulta fazendo a verificação de erros e mostrando os dados ou uma mensagem de erro na sequência, conforme o resultado.

Listagem 10. Consultando publicações


   13     //Consulta o Web Service
   14     private void btnConsultar_Click(object sender, EventArgs e)
   15     {
   16       wsPublicacao.Publicacao webPublicacao = new wsPublicacao.Publicacao();
   17       webPublicacao.Url = @"http://localhost/publicacao/publicacao.asmx";
   18       string mensagem;
   19       var Dados = webPublicacao.Consultar(txtEmail.Text, txtConsulta.Text, out mensagem);
   20 
   21       if (Dados == null || Dados.Rows.Count == 0)
   22       {
   23         if (string.IsNullOrEmpty(mensagem))
   24         {
   25           mensagem = "Nenhum registro retornado.";
   26         }
   27 
   28         MessageBox.Show(mensagem);
   29       }
   30       else
   31       {
   32         dataGridView1.DataSource = Dados;
   33       }
   34       }

Enviando os registros

Para o envio de um registro novo de publicação, criei um método que responde ao evento “Click” do botão OK e pode ser conferido na Listagem 11.

O método se inicia pedindo uma confirmação do usuário. Na linha 46 observe que está sendo criada uma instância da classe DadosPublicacao que foi criada no Web Service para armazenar os dados na operação de inclusão. Os dados são enviados para o objeto manualmente, mas, poderiam também estar ligados via Data Binding com os controles de texto da tela.

Em seguida é criada uma instância da classe referente ao Web Service na linha 57. Desta vez não alterei o endereço do mesmo, mas sempre isto será necessário em aplicações coorporativas.

A linha 60 faz uma chamada para o método de inclusão e exibe o resultado. Note que o campo contendo o e-mail do usuário é enviado nesta operação.

Na linha 67 é chamado um método que limpa os campos da tela após a operação bem sucedida. Este método pode ser conferido na Listagem 12.

O método LimparCampos percorre todos os controles da TabPage especificada e verifica, se for do tipo TextBox, faz uma conversão (linha 78) e atribui um valor vazio para o mesmo.

Faltou definir o evento Click para o botão Cancelar, que vai apagar tudo o que foi digitado. Como já defini a rotina que faz isto, o método deste botão precisa apenas chamar o método LimparCampos (Listagem 13).

Listagem 11. Inclusão de registro


   36     //Envia os dados para inclusão
   37     private void btnOk_Click(object sender, EventArgs e)
   38     {
   39       if (MessageBox.Show("Confirma o envio dos dados?", 
   40         "Confirmação", MessageBoxButtons.YesNo, 
   41         MessageBoxIcon.Question) != DialogResult.Yes)
   42       {
   43         return;
   44       }
   45 
   46       wsPublicacao.DadosPublicacao dados = new wsPublicacao.DadosPublicacao
   47       {
   48         Titulo = txtTitulo.Text,
   49         Autores = txtAutores.Text,
   50         PalavrasChave = txtPalavrasChave.Text,
   51         Publicacao = txtPublicacao.Text,
   52         Editor = txtEditor.Text,
   53         EnderecoEletronico = txtEndereco.Text,
   54         Data = DateTime.Today
   55       };
   56 
   57       wsPublicacao.Publicacao webService = new wsPublicacao.Publicacao();
   58       string erro = string.Empty;
   59 
   60       if (!webService.IncluirPublicacao(dados, txtEmail.Text, out erro))
   61       {
   62         MessageBox.Show(erro);
   63       }
   64       else
   65       {
   66         MessageBox.Show("Registro incluído com sucesso.");
   67         LimparCampos();
   68       }
   69     }

Listagem 12. Método para limpar os campos da tela


   71     //Limpa os campos da tela
   72     void LimparCampos()
   73     {
   74       foreach (Control ctrl in tabPage2.Controls)
   75       {
   76         if (ctrl is TextBox)
   77         {
   78           ((TextBox)ctrl).Text = string.Empty;
   79         }
   80       }
   81     }

Listagem 13. Evento do botão Cancelar


   83     private void btnCancelar_Click(object sender, EventArgs e)
   84     {
   85       LimparCampos();
   86     }

Conclusão

Web Services promovem a Internet para fazer muito mais além de disponibilizar conteúdo, mas também serviços para serem consumidos. Neste exemplo, usei o Web Service como alternativa de repositório de dados, mas muito mais pode ser feito.

Uma alternativa é fazer os Web Services disponibilizarem processamento de dados remotos. Considere, por exemplo, um serviço de análise e comparação de preços de produtos ou ainda, onde se enviam dados estatísticos e sejam feitas análises e sejam retornados estes dados analisados e com algumas críticas.

Os Web Services podem ainda interagir com outros tipos de aplicação como Web Sites e até mesmo os gadgets do Windows e de outras plataformas, enfim, são muitas as situações em que o processamento remoto pode ser usado.

Considere sempre estas possibilidades e busque saber mais sobre como os serviços pela Web vem evoluindo. Uma evolução natural para este estudo é a criação de aplicações WCF que poderá ser assunto de artigos futuros. Até a próxima oportunidade.

Saiu da DevMedia!

  • Minha primeira Single Page Application com Angular:
    Neste curso você aprenderá a criar uma Single Page Application com o Angular, um dos frameworks JavaScript para criação de aplicações client-side mais utilizados. Para isso, usaremos como cenário um Dashboard, que apresenta um resumo das consultas marcadas, assim como do faturamento de uma clínica médica.
  • 10 técnicas de otimização de consultas SQL:
    Neste artigo serão mostradas algumas técnicas que vão auxiliar na codificação das consultas a fim de obter o melhor tempo de resposta.
  • O que são Servlets?:
    A programação para a Web nem sempre foi a área mais forte do Java. No início, ficávamos restritos a scripts CGI e Applets. Com a criação da Servlet API, no entanto, esse cenário mudou e, como consequência, o Java se tornou a principal tecnologia para desenvolvimento Web.

Saiba mais sobre .NET ;)

  • Como aprender .NET na Prática:
    Neste Guia de Consulta você encontrará conteúdos que abordam na prática o desenvolvimento de aplicações em .NET utilizando seus variados frameworks, como ASP.NET MVC, Web API e Entity Framework.
  • ASP.NET MVC:
    Neste Guia de Referência você encontrará o conteúdo que precisa para aprender a desenvolver aplicações web com o framework ASP.NET MVC e a linguagem C#.
  • ASP.NET Web API:
    Neste Guia de Referência você encontrará o conteúdo que precisa para aprender a desenvolver web services RESTful com o framework ASP.NET Web API e a linguagem C#.
  • Web Services com .NET Framework:
    O artigo introduz um tipo de aplicação Web muito usado - os Web Services - dando o embasamento teórico e sua implementação com o Framework .NET e a linguagem C#. Também faz uma demonstração prática do uso deste tipo de aplicação com o Visual Studio.

Links

  • Web Services with ASP.NET
    Documentação oficial
    http://msdn.microsoft.com/en-us/library/ms972326.aspx
  • ASP.NET Web Services
    http://msdn.microsoft.com/en-us/library/t745kdsh.aspx
  • Introduction to Programming Web Services in Managed Code
    http://msdn.microsoft.com/en-us/library/yzbxwf53.aspx
  • .NET Web Services Tutorial
    http://www.codeguru.com/csharp/csharp/cs_webservices/tutorials/article.php/
    c5477
  • Top Ten FAQs for Web Services
    http://www.webservicex.net/ws/faq.aspx
  • W3C Web Services Tutorial
    http://www.w3schools.com/webservices/default.asp
  • Universal Description Discovery and Integration
    http://en.wikipedia.org/wiki/Universal_Description_Discovery_and_Integration
  • WSDL and UDDI
    http://www.w3schools.com/wsdl/wsdl_uddi.asp
  • Introduction to WSDL
    http://www.w3schools.com/wsdl/wsdl_intro.asp
  • WSDL Tutorial
    http://www.w3schools.com/wsdl/default.asp
  • Walkthrough on creating WCF 4.0 Service and Hosting in IIS 7.5
    http://debugmode.net/2010/09/07/walkthrough-on-creating-wcf-4-0-service-and-hosting-in-iis-7-5/
  • WCF Services and ASP.NET
    http://msdn.microsoft.com/en-us/library/aa702682.aspx
  • Introduction to WCF
    http://www.wcftutorial.net/Introduction-to-WCF.aspx
  • IIS 7 na Internet
    http://go.microsoft.com/fwlink/?LinkId=92350
  • Blogs
    http://vladimirrech.blogspot.com
    http://twitter.com/vladimirrech