Desenvolvimento - Web Services

Consumindo um WebService através de uma Aplicação ASP.NET para Dispositivos Móveis

Neste artigo, estaremos consumindo o WebService criado no artigo anterior (Criando um WebService para controle de Cliente utilizando C#) através de uma aplicação ASP.NET para dispositivos móveis (telefones celulares, PDA's, etc).

por Jones Avelino



Neste artigo, estaremos consumindo o WebService criado no artigo anterior (Criando um WebService para controle de Cliente utilizando C#) através de uma aplicação ASP.NET para dispositivos móveis (telefones celulares, PDA"s, etc) com o objetivo de mostrar os benefícios que a utilização de WebService nos trazem, além da facilidade para se desenvolver aplicações para dispositivos móveis utilizando o VisualStudio.NET.


Introdução a Aplicações ASP.NET para Dispositivos Móveis

O modelo de programação ASP.NET para dispositivos móveis é bem similar ao modelo de programação ASP.NET para páginas comuns (inclusive a mesma extensão de arquivo: .aspx) tendo como principal diferencial, os controles de servidor especializados para dispositivos móveis, responsáveis por possibilitar que uma única versão de uma página ASP.NET seja adaptada automaticamente de acordo com o dispositivo utilizado, ou seja, você pode acessar a sua página ASP.NET para dispositivos móveis através de qualquer celular, por exemplo, ou mesmo acessá-la normalmente através do navegador web do seu PC e os controles de servidor se encarregarão por exibir a sua página da forma mais adequada de acordo com o dispositivo que você esteja utilizando no momento. Para usarmos os recursos do .NET framework específicos para dispositivos móveis, precisamos ter instalado o Mobile Web SDK que consiste em um pacote do .NET framework extra que contém todos os arquivos, assemblies e namespaces que precisamos para criarmos páginas ASP.NET para dispositivos móveis (ele é instalado automaticamente quando instalamos o VisualStudio.NET).


Mas já que o modelo de programação de páginas ASP.NET comuns e para dispositivos móveis é praticamente o mesmo (inclusive a extensão .aspx), por que não trabalhamos somente com páginas ASP.NET comuns?

Apesar dos controles de servidor tanto para páginas ASP.NET comuns quanto para dispositivos móveis serem praticamente os mesmos (Ou pelo menos alguns deles. Ex: Label, TextBox, etc), internamente eles possuem mecanismos bem diferentes. Por exemplo, um controle de servidor Label para páginas ASP.NET comuns e para dispositivos móveis produzem o mesmo resultado final (exibir algum texto no navegador web), mas internamente possuem características diferentes, pois o controle para páginas comuns precisa apenas mostrar uma saída HTML comum, mas o controle para dispositivos móveis precisa primeiro preocupar-se com o dispositivo utilizado antes de exibir o texto solicitado. No caso de um telefone celular, por exemplo, é necessário levar em consideração o tamanho da tela e o mecanismo de paginação do dispositivo, ou até mesmo ter que transformar o resultado final para código WML (linguagem de marcação específica para dispositivos wireless como o telefone celular). Além disso, uma página ASP.NET comum deve possuir um único Formulário Web (que agrupa todos os controles que são processados no servidor) e já uma aplicação para dispositivos móveis podem possuir vários Formulários Web (WebForms), sendo que apenas um deles é exibido por vez (formulário ativo), permitindo a navegação entre eles como se fossem páginas diferentes, possibilitando desta forma, a construção de uma aplicação ASP.NET para dispositivos móveis completa utilizando apenas um único arquivo .aspx.

Em termos de comparação, para criarmos aplicações web para telefones celulares (claro que para aqueles que ainda não suportam HTML) sem a utilização de páginas ASP.NET, precisaríamos ter o domínio de uma linguagem totalmente específica e voltada somente para este fim, a WML (Wireless Modeling Language), a qual é também é uma linguagem de marcação como a HTML, mas foi projetada apenas para especificar interfaces com o usuário em dispositivos wireless.


Mas afinal: O que é "Consumir um WebService"?

No artigo anterior, construímos um WebService que tinha como objetivo controlar um cadastro de clientes fornecendo serviços de inclusão alteração, consulta, exclusão e autenticação dos clientes e vimos como a tarefa de integrar sistemas totalmente independentes se tornou fácil. Agora, se você precisa disponiblizar "partes" da sua aplicação à outros sistemas localizados onde quer que estejam, basta você criar um WebService e disponibilizá-lo através da internet, permitindo que os outros sistemas o "consuma", ou seja, utilizem o seu código (encapsulado e programado em seu servidor) como uma classe local que fornece atributos e métodos para a sua aplicação utilizar.

"Os WebServices fornecem um mecanismo muito simples para aplicativos se comunicarem entre si. Eles permitem que os componentes sejam compartilhados e que a funcionalidade seja entregue a qualquer pessoa, em qualquer lugar. Imagine nunca ter de instalar um outro programa em seu computador novamente, simplesmente conectar-se à Web e acessar o serviço". [Payne]

De fato, a comunicação realizada entre o WebService e a aplicação que está o consumindo pode ser realizada através de 3 protocolos de comunicação:

Http-Get
: as informações são enviadas como parte da URL (querystrings) na chamada do WebService, permitindo apenas o envio de pares contendo parâmetro/valor. Ex: teste.asmx?nome=valor&nome1=valor1&nome2=valor2

Http-Post
: é semelhante ao protocolo Http-Get mas ao invés de enviar as informações na própria URL, insere os pares de parâmetro/valor na requisição HTTP. Ex:
<form action="teste.asmx">
<input type="hidden" name="nome" value="valor">
<input type="submit">
</form>

O formulário HTML acima insere um parâmetro oculto (hidden) chamado "nome" com o valor "valor" na requisição HTTP e quando o formulário é enviado (através do botão submit), o servidor é capaz de extrair os pares de parâmetro/valor enviados.

SOAP
: o SOAP (Simple Object Access Protocol) é um padrão bem mais rico, pois ao invés de enviar apenas pares de parâmetro/valor, ele utiliza XML para transmitir informações, permitindo a transmissão de objetos mais complexos como classes, objetos, tipos ricos de dados, etc.


Como a comunicação entre o Consumidor e o WebService é realizada?

Como veremos daqui a pouco, o VisualStudio.NET torna o processo de comunicação entre a aplicação consumidora e o WebService totalmente transparente para o desenvolvedor, sendo necessário que a aplicação consumidora saiba apenas a localização do WebService, ou seja, sua URL. A partir da sua localização na Web, o VisualStudio.NET cria o que chamamos de Classe Proxy que é responsável por intermediar esta comunicação. O VisualStudio.NET automaticamente codificada e insere esta classe no assemblie da aplicação, ou seja, quando instanciamos o nosso WebService em nossa aplicação, na verdade estamos criando uma instância da classe de proxy a qual contém toda a funcionalidade necessária para transportar as requisições entre o Consumidor e o WebService.

Podemos também gerar a classe proxy através do utilitário de linha de comando WebService Description Language (wsdl.exe) que é distribuído juntamente ao .NET framework. Por exemplo, a partir do comando abaixo podemos gerar a classe de proxy para o nosso projeto:

wsdl.exe /language:C# /protocol:SOAP http://www.jjsolucoes.com.br/WsClientes/WsClientes.asmx?WSDL

A partir deste comando, será gerado o arquivo WsClientes.cs no diretório corrente, o qual contém todo o código (em C# devido a utilização da opção: /language:C#) necessário para realizar a comunicação entre o Consumidor e WebService através do protocolo SOAP (opção /protocol:SOAP).
Iniciando a construção da nossa aplicação

Agora que já sabemos algumas características das páginas ASP.NET para dispositivos móveis e já entendemos um pouco a comunicação realizada entre um WebService e uma Aplicação Consumidora, vamos desenvolver a nossa aplicação proposta pelo artigo. Vamos iniciar o VisualStudio.NET e crirar um novo projeto ASP.NET Mobile Web Application com o nome de clientes_mobile:


Automaticamente será criado alguns arquivos de configurações globais da aplicação como o web.config e o global.asax. Além desses arquivos, também será criado o arquivo MobileWebForm1.aspx. Vamos renomeá-lo para ControleClientes.aspx, onde criaremos todos os WebForms da nossa aplicação:


Nossa aplicação possuirá 4 WebForms sendo eles:
frmPrincipal: será o nosso formulário inicial que fornecerá os links para todas as funcionalidades da aplicação.
frmCadPessoaFis: será o nosso formulário de cadastro de uma nova pessoa física.
frmLoginPessoaFis: será o nosso formulário de autenticação (através de login e senha) para permitir que uma pessoa física altere os seus dados cadastrais.
frmAltPessoaFis: será o nosso formulário responsável pela alteração dos dados cadastrais de uma pessoa física.

Apesar do nosso formulário inicial (frmPrincipal) conter os links para as opções de cadastro e alteração de pessoa jurídica, não iremos implementá-las neste exemplo, pois estes formulários possuem praticamente a mesma funcionalidade dos formulários de pessoa física. Portanto, a implementação das opções de pessoa jurídica fica como exercício prático.

Em nosso formulário inicial (frmPrincipal) utilizamos o controle de servidor Link para inserir um link entre páginas. Altere a propriedade NavigateURL dos links Pessoa Física, em Cadastro de Clientes e Alteração de Cadastro, para ControleClientes.aspx?frm=cad_pf e ControleClientes.aspx?frm=login_pf respectivamente.


Como utilizaremos apenas um arquivo aspx para toda a nossa aplicação, identificaremos o formulário ativo da aplicação através do parâmetro frm no evendo Page_Load de nossa página:

private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
if(Request.Params["frm"] != null)
{
switch(Request.Params["frm"].ToString())
{
case "cad_pf":
ActiveForm = frmCadPessoaFis;
break;
case "login_pf":
ActiveForm = frmLoginPessoaFis;
break;
case "alt_pf":
ActiveForm = frmAltPessoaFis;
break;
default:
ActiveForm = frmPrincipal;
break;
}
}
}
}

Utilizamos o evento Page_load da página para definirmos qual será o formulário ativo (que será exibido) da página. O método IsPosBack do objeto Page indica se á página está sendo submetida (PostBack). O código acima indica o formulário ativo (ActiveForm) da página de acordo com o parâmetro frm passado através da URL. Caso não seja enviado nenhum valor para o parâmetro formulário, ele usa o default: frmPrincipal.

A figura abaixo exibe a continuação da nossa página (ControleClientes.aspx), mostrando os formulários restantes (frmLoginPessoaFis e frmResultAlt). Além disso, ela indica os outros controles de servidor que estamos utilizando em nossa aplicação: Label, TextBox e Command.


Antes de implementar o código dos nossos WebForms, vamos consumir o nosso WebService através do VistualStudio.NET. No Solution Explore, clique com o botão direito em cima do projeto clientes_mobile e clique sobre a opção Add WebReference. A seguinte tela será mostrada:

O VisualStudio.NET disponibilizará um "mini browser" e a partir dele informamos a URL do nosso WebService. Para que todos possam testar o funcionamento da nossa aplicação, publiquei o nosso WebService desenvolvido no artigo anterior no endereço http://www.jjsolucoes.com.br/WsClientes/WsClientes.asmx. Agora, basta indicarmos um nome para a referência criada em Web reference name, no nosso caso, daremos o nome de clientes. Na verdade, este nome será dado a classe de proxy utilizada para realizar a comunicação entre a nossa aplicação e o WebService.

Vamos agora implementar o código dos nossos formulários, começando pelo formulário de cadastro de pessoa física (frmCadPessoaFis):

private void frmCadPessoaFis_Activate(object sender, System.EventArgs e)
{
lblResultCad.Visible =
false;
}

private void btCadastrar_Click(object sender, System.EventArgs e)
{
try
{

clientes.WsClientes ws =
new clientes.WsClientes();
ws.incluirPF(txtNome.Text, txtEmail.Text, txtTel.Text, txtLogin.Text, txtSenha.Text,
txtCPF.Text, Convert.ToDateTime(txtDtNasc.Text), txtRG.Text);

lblResultCad.Text = "Cadastro realizado.";
}
catch
{
lblResultCad.Text = "Serviço indisponível no momento."
}
lblResultCad.Visible = true;
}


Utilizamos o evento Activate (para criá-lo, basta dar um clique duplo sobre o formulário desejado) para "ocultar" o nosso controle Label responsável por exibir as mensagens de sucesso ou falha da operação proposta pelo formulário (incluir uma pessoa física).

Nosso botão Cadastrar será responsável por criar uma instância do nosso WebService e executar o método incluirPF para realizar a inclusão. Executando a nossa operação dentro do bloco try e catch, podemos exibir uma mensagem de erro personalizada, caso o nosso WebService não esteja disponível no momento que tentarmos utilizá-lo.

Agora, vamos implementar a opção de alteração do cadastro de uma pessoa física que será realizada através dos dois formulários restantes do nosso projeto (frmLoginPessoaFis e frmAltPessoaFis). O formulário de autenticação (frmLoginPessoaFis) será responsável por verificar (através do seu login e senha) se uma pessoa física é cadastrada, e retornar o seu código de cadastro, permitindo que o formulário de alteração (frmAltPessoaFis) utilize este código para obter os dados da pessoa (através de um DataSet) e carregue os controles TextBox para alteração dos dados.

private void frmLoginPessoaFis_Activate(object sender, System.EventArgs e)
{
Session.Remove("cod_alt_pf");
lblMsgErro.Visible =
false;
}

private void btAutentica_Click(object sender, System.EventArgs e)
{
try
{
clientes.WsClientes ws =
new clientes.WsClientes();
long cod = ws.autenticar(txtLoginAut.Text, txtSenhaAut.Text);
if(cod == 0)
{
lblMsgErro.Text = "Cliente inexistente";
}
else
{
Session.Add("cod_alt_pf", cod.ToString());
ActiveForm = frmAltPessoaFis;
}
}
catch
{
lblMsgErro
.Text = "Serviço indisponível no momento."
}
lblMsgErro.Visible =
true;
}

Como no formulário anterior (frmCadPessoaFis), também utilizamos o evento Activate para "ocultar" o controle Label para exibição de mensagens de erro (lblMsgErro). No evento Click do botão btAutenticar, criamos uma instância do nosso WebService e chamamos o método autenticar passando como parâmetro o login e senha informados através do nosso WebForm.

Caso o cliente seja autenticado (cod <> 0), o seu código é retornado e armazenado em uma Variável de Sessão (cod_alt_pf) e o formulário de alteração de cadastro é exibido (ActiveForm = frmAltPessoaFis). Como podemos ver, podemos utilizar variáveis de sessão como no ASP tradicional.

Agora, vamos implementar o nosso formulário de alteração de cadastro. O formulário é praticamente idêntico ao formulário de cadastro de pessoas físicas mas com funcionalidades diferentes:

private void frmAltPessoaFis_Activate(object sender, System.EventArgs e)
{
lblResultAlt.Visible =
false;
if(Session["cod_alt_pf"] == null)
{
ActiveForm = frmLoginPessoaFis;
}
else
{
try
{

clientes.WsClientes ws = new clientes.WsClientes();
DataSet ds = ws.obterPF(Convert.ToInt64(Session["cod_alt_pf"]));
if(ds != null)
{
txtNomeAlt.Text = ds.Tables[0].Rows[0]["nome"].ToString();
txtEmailAlt.Text = ds.Tables[0].Rows[0]["email"].ToString();
txtTelAlt.Text = ds.Tables[0].Rows[0]["telefone"].ToString();
txtLoginAlt.Text = ds.Tables[0].Rows[0]["login"].ToString();
txtSenhaAlt.Text = ds.Tables[0].Rows[0]["nome"].ToString();
txtCPFAlt.Text = ds.Tables[0].Rows[0]["cpf"].ToString();
txtDtNascAlt.Text = ds.Tables[0].Rows[0]["dtnasc"].ToString();
txtRGAlt.Text = ds.Tables[0].Rows[0]["rg"].ToString();
}
}
catch
lblResultAlt.Text = "Serviço indisponível no momento.";
lblResultAlt.Visible =
true;
}
}
}

private
void btAlterar_Click(object
sender, System.EventArgs e)
{
try
{

clientes.WsClientes ws =
new clientes.WsClientes();
ws.alterarPF(
Convert.ToInt64(Session["cod_alt_pf"]), txtNomeAlt.Text,
txtEmailAlt.Text, txtTelAlt.Text,
txtLoginAlt.Text, txtSenhaAlt.Text, txtCPFAlt.Text,
Convert.ToDateTime(txtDtNascAlt.Text), txtRGAlt.Text);
lblResultAlt.Text = "Alteração realizada!";
}
catch
{
lblResultAlt.Text = "Serviço indisponível no momento.";
}
lblResultAlt.Visible = true;
}


No momento em que o formulário é ativado, verificamos se há algum código de cliente em nossa variável de sessão criada no formulário de autenticação (Session["cod_alt_pf"] == null). Existindo algum código em nossa variável de sessão, é necessário carregarmos os dados do cliente pessoa física, para tanto, criamos uma instância do nosso WebService e chamamos o método obterPF passando o código do cliente. O retorno deste método é um objeto DataSet o qual utilizamos para preencher os controles TextBox responsáveis por exibir os dados da pessoa física e permitir a alteração dos mesmos. Note que temos que fazer a vinculação dos dados nos controles TextBox "na mão", pois estes controles para dispositivos móveis não propriedades de vinculação.

Utilizamos o evento Click do botão alterar (btAlterar) para criar uma instância do nosso WebService e chamar o método de alteração de clientes pessoa física (alterarPF).

Agora, vamos testar a nossa aplicação através do browser:


Página inicial (frmPrincipal)


Formulário de Cadastro de Pessoa Física
(frmCadPessoaFis)


Formulário de Autenticação para alteração
de cadastro de Pessoa Física (frmLoginPessoaFis)


Formulário de Alteração de cadastro de
Pessoa Física (frmAltPessoaFis)


Pronto! A nossa aplicação para dispositivos móveis que utiliza o nosso WebService para controle de clientes está finalizada.

Este artigo demonstrou como desenvolver aplicações para dispositivos móveis se tornou extremamente simples com a utilização do VisualStudio.NET e os recursos do .NET Framework. "Não" precisamos mais nos "preocupar" com o dispositivos que estamos utilizando, não tendo mais a necessidade de se criar várias versões de uma mesma aplicação para dispositivos diferentes.

Além disso, vimos como a utilização de WebServices nos fornece um incrível mecanismo para a integração de sistemas em qualquer lugar que estejam, permitindo disponibilizarmos "partes" da nossa aplicação para qualquer sistema em qualquer lugar.

Nos próximos artigos, estarei abordando a utilização da UML (Unified Modeling Language) para especificarmos um Fórum de Discussão e depois implementá-lo através de uma aplicação ASP.NET com C#.

Clique aqui para baixar o código fonte da nossa aplicação.

Um abraço!!!

Jones Avelino


Referências:
PAYNE, Chris. Aprenda ASP.NET em 21 Dias; tradução de Edson Furmankiewicz. Rio de Janeiro: Campus, 2001.

.NET Mobile Tutorial. Disponível em http://www.w3schools.com/dotnetmobile/default.asp. Último acesso em 02/05/2005.

Jones Avelino

Jones Avelino - Bacharel em Sistemas de Informação e com especialização em Desenvolvimento de Sistemas para Internet, trabalha como Analista / Desenvolvedor de sistemas Web sendo especialista em ASP, ASP.NET e SQL Server.