Invocando PageMethods diretamente com JQuery    

Olá pessoal!

Apesar de já ter tratado de PageMethods em um dos meus primeiros posts, vou falar um pouco mais dele novamente, porque vejo que muita gente ainda não entendeu com funciona, o que torna difícil a utilização do mesmo de outra forma que não seja através do proxy que o próprio Asp.Net cria no JavaScript.

Para entender o básico, veja o primeiro post sobre o assunto, para eu não precisar repetí-lo aqui.

Resumidamente, adicionamos um PageMethod criando um método estático em uma página, e decorando esse método com o atributo [WebMethod]. E no JavaScript acessamos esse método através do proxy no JavaScript da seguinte forma: PageMethods.[NomeDoMetodo].

Basicamente o Asp.Net disponibiliza o método como um WebService, e o JavaScript acessa o mesmo através da classe XmlHttpRequest.

Mas por que muitas vezes não conseguimos acessar esses métodos através do JQuery? Alguns Plugins como JQGrid e Auto-Complete as vezes têm certa dificuldade de conseguir enviar o chamado ou processar a resposta. Vamos a alguns exemplos.

Vou fazer um código bem simples, meu PageMethod vai ser assim:

   1: [WebMethod]
   2: public static string ObterPessoa()
   3: {
   4:     return "Retorno do Server";
   5: }

E meu JavaScript:

   1: $().ready(function () {
   2:     $.ajax({
   3:         url: "Default.aspx/ObterPessoa",
   4:         success:retorno
   5:     });
   6: });
   7:  
   8: function retorno(data) {
   9:     alert(data.d);
  10: }

Veja que o código é bem simples. Estou utilizando o mínimo do método ajax do JQuery, ou seja, os demais valores estão sendo utilizados os valores Default. Vendo o código, o retorno deveria uma alerta do JavaScript com o valor “Retorno do Server”. Mas a resposta é: Nada! Exatamente, nada acontece, inclusive não retorna erro algum.

Nesse momento é que o desenvolvedor começa a passar as mãos na testa e falar: “Maldito Murphy!”.

Se olharmos as chamadas o Fiddler ou outra ferramenta que monitora os Requests, teremos algumas informações interessantes. Na minha IE Developer Toolbar tenho as seguintes informações (clique para ampliar):

image

Perceba que na última linha tem a minha chamada para o PageMethod, sem erro, mas com um código diferente (304). Lembre que códigos de erros são apenas os 4xx e 5xx, ou seja, de fato não houve erro.

O HTTP Return Code 304 indica que o arquivo (ou resource) solicitado não teve alteração, ou seja, o Browser pode obter o valor do cache se quiser, ou solicitar a página mesmo assim. Então pense, se aparentemente é a primeira vez que estamos chamando o método, por que ele está falando que já está em cache? Qual será o retorno? Vamos dar uma olhada no retorno (clique para ampliar):

image

Veja que é o próprio código da página, e não do PageMethod, ou seja, o Asp.Net, ao receber o Request, está entendendo que o que está sendo solicitado é a página e não o método.

Isso acontece porque estamos invocando o método com o verbo HTTP GET, e a primeira coisa que devemos saber é que PageMethods só funciona com HTTP POST!

Outra coisa que podemos ver na primeira imagem, é que o tipo da solicitação é “text/html” e o retorno do Asp.Net está de acordo, ou seja, o texto HTML da página.

Portanto, a segunda coisa que devemos saber é que para o PageMethod funcionar é que o tipo da requisição deve ser json ou xml.

Vamos mudar apenas essas duas coisa e ver o que acontece:

   1: $().ready(function () {
   2:     $.ajax({
   3:         type: "post",
   4:         contentType: "application/json", 
   5:         url: "Default.aspx/ObterPessoa",
   6:         success:retorno
   7:     });
   8: });
   9:  
  10: function retorno(data) {
  11:     alert(data.d);
  12: }

E os prints da Developer Toolbar:

image

Veja que algumas coisas mudaram:

Primeiro que o método agora é POST e o código do retorno é 200, ou seja, sucesso (OK). Além disso, o tipo da requisição também mudou, sendo agora application/json. Só o fato dessas informações terem mudado já é alguma coisa. Mas vamos ver o retorno:

image

E o alerta, como o esperado.

image

Assim já fazemos nosso PageMethod funcionar. Poderíamos terminar o post por aqui, mas tem mais algumas coisas que precisamos saber, por exemplo, como eu passo parâmetros?

Passando parâmetros para PageMethods com JQuery

Vou mudar meu PageMethod e meu JavaScript para passar parâmetros. A alteração é muito simples, preciso apenas passar meu dados no formato JSON, assim o Asp.Net vai saber converter os dados do requests para os parâmetros do método. Vamos lá:

   1: [WebMethod]
   2: public static string ObterPessoa(string nome, string idade)
   3: {
   4:    return string.Format("Nome {0}. Idade {1}",nome,idade);
   5: }

E o JavaScript:

   1: $().ready(function () {
   2:    $.ajax({
   3:        type: "post",
   4:        contentType: "application/json",
   5:        url: "Default.aspx/ObterPessoa",
   6:        success: retorno,
   7:        data: '{nome:"Frederico",idade:"25"}'
   8:    });
   9: });
  10:  
  11: function retorno(data) {
  12:    alert(data.d);
  13: }

Dessa forma conseguimos passar os dados, e podemos ver com o alerta que o retorno foi como o esperado:

image

Conclusão

Vimos que é possível invocar PageMethods do JQuery sem muito esforço. Precisamos apenas saber quais parâmetros passar na chamada. Muitas vezes nossos plugins não funcionam com PageMethods porque não sabemos quais parâmetros utilizar. Uma vez que já sabemos, fica fácil.

Tenha em mente que para um PageMethod funcionar, você deve invocá-lo:

  • Utilizando o verbo Post
  • Utilizando o Content-Type como application/json.

Isso já é suficiente para funcionar.

Se você vai invocar muitas vezes métodos através do Ajax do JQuery, você pode alterar os valores Defaults e invocar de forma mais sucinta, da seguinte forma:

   1: $().ready(function () {
   2:     $.ajaxSetup({
   3:         type: "post",
   4:         contentType: "application/json"
   5:     });
   6:     
   7:     //E chamar sem precisar configurar novamente.
   8:     $.ajax({
   9:         url: "Default.aspx/ObterPessoa",
  10:         success: retorno,
  11:         data: '{nome:"Frederico",idade:"25"}'
  12:     });
  13: });

Essa tática é muito boa para utilizar com plugins, afinal, você não consegue (ou não deve) alterar a chamada internas dos plugins, como o JQGrid, então assim você alterar o padrão, para que o plugin utilize o método $.ajax da forma que você deseja.

O interessante de utilizar JQuery, é que você não precisa utilizar o ScriptManager com EnablePageMethods igual a true, porque você não precisará do Proxy do JavaScript. Sua página ficará consideravelmente mais leve se você tiver vários PageMethods em uma página só.

Em breve publicarei um breve post para explicar o porquê do “.d” no retorno do PageMethods, o que também muitas vezes dificulta a utilização de PageMethods com plugins JQuery.

Bom pessoal, espero que ajude. Até o próximo.

16. August 2011 09:32 by Frederico B. Emídio | Comments (1) | Permalink

Utilizando Ajax com as facilidades do Asp.Net    

No último post, comentei que é uma tendência a utilização cada vez maior de Ajax nas aplicações Web. Particularmente acredito que a única utilidade de se utilizar WebForms em aplicações web hoje em dia é se for com uso de Ajax, junto com uma boa quantidade de JavaScript, para fazer a experiência do usuário ser cada vez melhor.

Tudo bem, podemos falar que é muito fácil de desenvolver, é só clicar e arrastar e tudo mais. Mas é fato que os usuários hoje cada vez mais querem uma experiência rica ao utilizar uma aplicação. Quanto mais próximo do desktop melhor. A única experiência próxima do desktop que existe utilizando o simples WebForm é a que o próprio desenvolvedor experimenta, que muitas vezes acredita que Web é só clicar e arrastar, como no WindowsForm, e que com um UpdatePanel tudo se resolve sem “refresh”.

Ledo engano. As telas vão ficando cada vez mais complexas, com mais requisições ao servidor, e ai um simples clique em um DropDownList, com AutoPostBack, demora 5 segundos para chegar em um botão, e o usuário já não fica tão satisfeito assim.

Este é o primeiro post de uma pequena série que vou falar da biblioteca Client Side do Asp.Net, e das capacidades Server Side que auxiliam no acesso ao Server dos códigos Client Side. O objetivo é que no final desta série você consiga desenvolver um site Asp.Net, com WebForm, que consiga proporcionar ao usuário um experiência pelo menos melhor que a normal.

Não utilizarei bibliotecas javascripts como JQuery, porque o objetivo aqui é falar das bibliotecas do Asp.Net.

PageMethods

Vamos começar falando de PageMethods, uma técnica que ainda não é muito utilizada no WebForms, mas que facilita muito a utilização de Ajax em páginas Asp.Net.

PageMethods são métodos de uma página WebForm, expostos como um WebMethods. Quando utilizamos PageMethods, a página web se torna um mini WebServices, inclusive, podendo ser utilizada por qualquer tecnologia que acesse métodos HTTP, como WCF, Java, ou um simples código JavaScript que faz uso do objeto XMLHttpRequest, como o JQuery.

Para criar um método HTTP em uma página é muito simples, basta criar um método estático decorado com o atributo WebMethod, localizado no namespace System.Web.Services. Eexemplo:

 [WebMethod]

        public static string Teste(string nome)
        {
            return string.Concat("Olá ", nome, ".");
        }

 Apenas assim já conseguiríamos utilizar este método método via XMLHttpRequest, ou pelo método Ajax do JQuery.

Mas para ficar interessante, é interessante adicionarmos o controle ScriptManager, do Asp.Net Ajax, à página, com a propriedade EnablePageMethods setada com o valor True:

<asp:ScriptManager runat="server" ID="maganger" EnablePageMethods="true"></asp:ScriptManager>

Desta forma, o Asp.Net criará um Proxy para o método na página, encapsulando no objeto PageMethods no ClientSide.

Para invocar o método, precisamos apenas chamar o método definido no ServerSide através do objeto PageMethods no Client Side, passando como parâmetro os parâmetros definidos no Server Side (nome caso do exemplo, o parâmetro nome), além de um método para receber o retorno no caso de sucesso e o retorno no caso de falha (exception):

PageMethods.Teste(“Frederico”,callbackSucesso,callbackErro);

O método de retorno de sucesso tem como parâmetros, o retorno do PageMethods, caso haja, como primeiro parâmetro, e os demais parâmetros são informações de contexto, informações de conexão, etc. Para hoje, precisamos apenas saber do primeiro parâmetro, o retorno do PageMethod Teste

No caso do retorno de falha, o primeiro parâmetro é a exceção, inclusive com StackTrace, para o momento precisamos apenas conhecimento do primeiro parâmetro também.

Para testarmos o método acima podemos fazer a seguinte página:

 

Ao clicarmos no botão Testar, a requisição irá assíncrona até o servidor e voltará, preenchendo o parágrafo de resposta:

 

Com isso já conseguimos ver o funcionamento básico de um PageMetho, porém, o mais legal é que um PageMethods te dá a possibilidade de trabalhar com classes complexas do .Net, ou seja, conseguimos enviar e receber classes de negócios por PageMethods, de forma totalmente transparente.

Imagine que temos um cadastro de pessoas, onde os dados necessários são Nome e e-mail, teremos uma classe assim:

O código abaixo, em HTML/Javascript, mostra como salvar esta classe com PageMethods, com a utilização de um objeto javascript criado com JSON:

 

Perceba que ao clicar no botão salvar:

 

Conseguimos colocar um breakpoint no PageMethods e verificar o conteúdo no lado do Server:

Com isso podemos utilizar qualquer coisa no lado do servidor, como o EntityFramework para persistência. E se quisermos retornar um classe, apenas temos que mudar o tipo do Retorno, que o método callback de sucesso retornará no primeiro parâmetro a classe oriunda do servidor.

Conclusão

A idéia deste post foi dar apenas uma introdução ao PageMethods, para que possamos começar a usar essa velha tecnologia que já está no Asp.Net desde a primeira versão do Asp.Net Ajax Framework, no .Net 2.0, mas que muita gente ainda desconhece.

Temos muitas peculiaridades que abordaremos em posts futuros. Espero que isto possa ajudar alguns de vocês que desconhecem esta tecnologia.

Abraços e até a próxima.

 

 

 

 

 

 

9. August 2010 08:37 by Frederico | Comments (5) | Permalink

Sobre mim

Minha Imagem

Meu nome é Frederico Batista Emídio, trabalho com desenvolvimento de sistemas profissionalmente a oito anos, porém, já faço sites pessoais a pelo menos dez anos.

Para saber mais clique aqui.

Páginas

Calendário

<<  September 2020  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET