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. agosto 2011 09:32 by Frederico B. Emídio | Comments (1) | 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

<<  novembro 2017  >>
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET