ASP.NET – Como chamar um método server-side por Ajax no WebForms

PageMethods no ASP.NET

Primeiro, um pouco de história. Pule para se você estiver a fim de ir direto para o código.

Faz tempo que queria publicar este macete. Gosto de chamá-lo assim pois foge um pouco da linha de pensamento de quem programa há muito tempo usando WebForms. Chamadas AJAX tornaram-se algo tão natural no mundo web que quase não se pensa em sistema sem pelo menos uma chamada dessas. E, convenhamos, não é algo que o WebForms faz muito bem.

É claro que sempre tivemos o AJAX Control Toolkit (ACT) em mãos, mas assim como todo o “disfarce” que o WebForms faz sobre o protocolo HTTP, o ACT não faz diferente.

Mas e se for preciso fazer uma simples chamada a um método, mesmo que isso seja um retorno de um array de strings, ou um JSON, como fica? Há formas de fazê-lo se você pensar em um Handler puro (ASHX), mas você teria que re-estruturar toda sua aplicação só por conta disso. Mas calma, existe um jeito “bonito” de fazer isso. PageMethods!

PageMethods

Até agora não consegui encontrar uma explicação boa sobre o que são PageMethods. O que entendi foi, PageMethods são uma forma de expor funções server side da sua página ASP.NET WebForms para ser chamada por Javascript. Um exemplo é a melhor maneira de entender.

O que é preciso para usar PageMethods?

Primeiro, uma página ASPX. A página ou sua MasterPage deve possuir um controle ScripManager e nele, a propriedade EnablePageMethods definida para true.

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

Se o ScriptManager já existir, basta acrescentar a propriedade, sem precisar mexer em referências que já existam.

Agora, a função que será chamada do lado server side. Como esta função trafegará por HTTP, o retorno desta precisa ser um tipo serializável, ou seja, que tenha uma representação em texto. No caso do exemplo, vamos retornar uma string simples. Crie a seguinte função no código da sua página:

[WebMethod]
// Get session state value.
public static string GetSessionValue(string key)
{
   return (string)HttpContext.Current.Session[key];
}
 
[WebMethod]
// Set session state value.
public static string SetSessionValue(string key, string value)
{
     HttpContext.Current.Session[key] = value;
     return (string)HttpContext.Current.Session[key];
}

Como é possível notar, o exemplo “brinca” com variáveis de servidor para provar que o trabalho está ocorrendo nele, e não no cliente. Os detalhes importantes são:

  • a função precisa retornar um tipo serializável
  • a função precisa ser static
  • a função precisa ser marcada com o atributo [WebMethod] do namespace System.Web.Services.

Por fim, o Javascript que vai chamar as funções. O código é auto explicativo. O importante a saber é que as funções criadas no código servidor serão expostas no Javascript através do objeto/function PageMethods. Assim, a função GetSessionValues criada no servidor será chamada no javascript com a sintaxe “PageMethods.GetSessionValues(parâmetros)”.

Além dos parâmetros da própria função, o PageMethods insere dos argumentos em cada uma delas, sendo eles duas funções que devem ser criadas na página, OnSucceeded e OnFailed. A primeira é invocada quando a chamada AJAX ocorre sem erros. A segunda serve exatamente para tratar erros vindos desta chamada. Veja mais detalhes no código:

// Initializes global variables and session state.
function pageLoad()
{
    PageMethods.SetSessionValue("SessionValue", Date(), 
        OnSucceeded, OnFailed);
}
 
// Gets the session state value.
function GetSessionValue(key) 
{
    PageMethods.GetSessionValue(key, OnSucceeded, OnFailed);
}
 
//Sets the session state value.
function SetSessionValue(key, value) 
{
    PageMethods.SetSessionValue(key, value, OnSucceeded, OnFailed);
}
 
// Callback function invoked on successful 
// completion of the page method.
function OnSucceeded(result, userContext, methodName) 
{
    if (methodName == "GetSessionValue")
    {
        alert("Current session state value: " + result;
    }
}
 
// Callback function invoked on failure 
// of the page method.
function OnFailed(error, userContext, methodName) 
{
    if(error !== null) 
    {
        alert( "An error occurred: " + error.get_message());
    }
}

O código pode ser colocado diretamente na página ou num arquivo Javascript separado.

Voilá! Temos AJAX de verdade do WebForms! Pelo menos quase isso.

Referências

http://www.asp.net/ajax/documentation/live/ViewSample.aspx?sref=Sys.Net.PageMethod/cs/PageMethod.aspx

VBA – Verificando se o site está online

Mais uma que veio do fórum, que como já disse inúmeras vezes, é um espaço pelo qual sou apaixonado.

A pergunta era simples. Como verificar se um site está online. Ao procurar uma alternativa simples, cheguei no seguinte post do site MrExcel (excelente referência em Excel VBA):

http://www.mrexcel.com/forum/excel-questions/707305-excel-visual-basic-applications-check-if-certain-website-online.html

Que nos deu a seguinte função:

Function getHtmlFromUrl(pURL As String) As String
     Dim resText As String
     Dim objHttp As Object
     Set objHttp = CreateObject("MSXML2.ServerXMLHTTP")
     objHttp.Open "GET", pURL, False
     objHttp.Send ""
     getHtmlFromUrl = Mid(objHttp.ResponseText, 1, 255) 
End Function

Essa função utiliza a biblioteca MSXML2.ServerXMLHTTP para fazer uma requisição para uma URL válida e retorna o texto de resposta. Útil, porém, para somente checar se o site está online, não é necessário ler todo o HTML. Basta checar seu status, ou o HTTP Code da resposta. Se for 200, está tudo ok!

Por fim, transformei o código acima no seguinte:

Sub EstaOnline()
 Debug.Print IsSiteOnline("http://www.tomasvasquez.com.br")
End Sub
 
Function IsSiteOnline(pURL As String) As Boolean
On Error GoTo TrataErro
 Dim resText As String
 Dim objHttp As Object
 Set objHttp = CreateObject("MSXML2.ServerXMLHTTP")
 objHttp.Open "GET", pURL, False
 objHttp.Send ""
 IsSiteOnline = objHttp.Status = 200
 
TrataSaida:
 Exit Function
TrataErro:
 IsSiteOnline = False
 GoTo TrataSaida
End Function

Como apoio, criei a SubOnline como exemplo de chamada para a IsSiteOnline, que faz a verificação e retorna True se estiver, False, do contrário.

Para saber mais sobre o ServerXMLHTTP:

http://msdn.microsoft.com/en-us/library/ms766431(v=vs.85).aspx

Arquivo do exemplo:

http://www.tomasvasquez.com.br/forum/download/file.php?id=2246

Bom proveito!