quinta-feira, 1 de outubro de 2009

Criando e Consumindo Serviços no Silverlight - Parte 2


Introdução

Demorei mais do que eu pensava para escrever, estou tendo bastante correria no serviço graças as mudanças nas leis sobre PAF-ECF.
Mas isso é assunto para outro post talvez...

Voltando ao assunto, no post anterior eu demonstrei como se cria um serviço para ser utilizado no Silverlight. Agora vamos utiliza-lo!

Criando um Aplicativo Silverlight

Vamos criar um projeto silverlight no Visual Studio:


Figura 1 - Criando um Projeto Silverlight

Figura 1 - Criando um Projeto Silverlight

Apos criado o projeto vamos abrir (se já não estiver aberto) o arquivo MainPage.xaml, vamos colocar um TextBlock e um botão para testar o serviço.
Você pode fazer isso alterando o código XAML ou pelo Expression Blend.

Código XAML

<Grid x:Name="LayoutRoot" Background="White">
<StackPanel>
        <TextBlock x:Name="lbResposta" Height="20" Width="100" Text="Resultado: "/> 
<Button x:Name="btAcessar" Height="20" Width="100" Content="Acessar"/>
</StackPanel>
</Grid>

Referenciando o Serviço

Vamos referenciar o serviço, você pode clicar com o botão direito no seu projeto e ir no Add Service Reference.

Figura 2 - Acessando o Menu
Figura 2 - Acessando o Menu

Uma tela abrirá, coloque o endereço do seu serviço em 'Address' e click em 'Go'.
Apos ele encontrar o serviço você pode definir um nome para o namespace e confirmar clicando em 'Ok' como ilustrado na imagem abaixo.
Esse processo é igual para uma aplicação desktop.

Figura 3 - Referenciando o Serviço

Figura 3 - Referenciando o Serviço

Crie um método para o evento click do botão, você pode fazer com o Expression Blend ou por código xaml que o Visual Studio ajuda.

Figura 4 - Criando o Evento do Botão por XAML

Figura 4 - Criando o Evento do Botão por XAML

Instanciando um Serviço e Vinculando Eventos

No MainPage.cs vamos declarar o serviço como um atributo(no escopo da classe), e no construtor vamos instanciar o serviço. No evento click do botão vamos chamar o método do serviço. A classe ficará assim:

C#

public partial class MainPage : UserControl
    {
        private ServiceReference1.MeuServicoClient ws;

        public MainPage()
        {
            InitializeComponent();
            ws = new ServiceReference1.MeuServicoClient();
        }

        private void btAcessar_Click(object sender, RoutedEventArgs e)
        {
            ws.DizOiAsync();
        }
    }

VB.Net

Public Partial Class MainPage
    Inherits UserControl
    Private ws As ServiceReference1.MeuServicoClient
    
    Public Sub New()
        InitializeComponent()
        ws = New ServiceReference1.MeuServicoClient()
    End Sub
    
    Private Sub btAcessar_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
        ws.DizOiAsync()
    End Sub
End Class

Você percebeu que o método 'DizOiAsync' não retorna nada?
Os métodos do web service executam de modo assíncrono, o programa não espera ele executar para continuar rodando (isso é ótimo).

Na instancia do serviço('ws') há um evento 'DizOiCompleted', apenas precisamos inscrever o método nesse evento e receber o resultado.
Quando ele receber uma resposta do serviço ele irá disparar esse evento.

Para inscrever o evento precisamos de um método que satisfaça a assinatura(cabeçalho) do evento. Essa assinatura segue o padrão dos parâmetros 'object' e o 'EventArgs', no caso do EventArgs há um especializado do serviço que é o DizOiCompletedEventArgs, esse EventArgs tem uma propriedade Result que é a resposta do serviço.

Resumindo o método deve ter uma assinatura assim '(objet, DizOiCompletedEventArgs)', depois é só vincular como mostra o código abaixo:

C#

public MainPage()
{
 //(...) código já implementado do construtor da classe
 ws.DizOiCompleted += new EventHandler<ServiceReference1.DizOiCompletedEventArgs>(ws_DizOiCompleted);
}

private void ws_DizOiCompleted(object sender, ServiceReference1.DizOiCompletedEventArgs e)
{
 lbResposta.Text = e.Result;
}

VB.Net

Public Sub New()
    '(...) código já implementado do construtor da classe
    AddHandler ws.DizOiCompleted, AddressOf ws_DizOiCompleted
End Sub

Private Sub ws_DizOiCompleted(ByVal sender As Object, ByVal e As ServiceReference1.DizOiCompletedEventArgs)
    lbResposta.Text = e.Result
End Sub

Agora basta executar a aplicação e ver o resultado.

Detalhes

Qualquer exceção que ocorrer dentro do web service retornará uma mensagem 'The remote server returned an error: NotFound.', por esse motivo é bom tratar as exceções dentro do serviço, pois essa mensagem não quer dizer nada.

Outro detalhe é que para executar o silverlight consumindo os serviços fora do servidor(debuggar por exemplo) precisa de um arquivo de configuração o Cross Domain Policy na raiz do seu servidor, você pode ver detalhes nesse post no blog do Tim Heuer. É bem simples.

Até a próxima,
Tiago Esmeraldino

Nenhum comentário:

Postar um comentário