ASP.NET – How to call a server side method through Ajax in WebForms

[TRANSLATING – If you are reading the text below in portuguese, it’s because I’m lazy e I still not finished the translation. Keep calm, drink a coffee and come back a few minutes, or hours, or days…]

PageMethods in ASP.NET

First, a bit of history. If you want to read the code now, click >here!

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 – Check if site is online

And here is one more gift from our forum. I love the forum (Did I already say that?).

It was a simple question: How do I check if a site is online? Ok, after a rapid internet search, I’ve found a interesting post on MrExcel forum (by the way, it’s excellent!):

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

It brought to us the function below:

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

The function uses the MSXML2.ServerXMLHTTP library to create a request to a valid URL and returns the HTML of response. It is useful, but, it’s to much if you only want to check if the site is online. The only thing you need to check is the HTTP Code. If the code is 200, everything is ok!

So, I’ve changed the code a bit to this (my apologies for the portuguese names, but, you know, this is a brazilian blog – 🙂 ):

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

I’ve created the EstaOnline Sub as an example of how to call the IsSiteOnline function, which returns a boolean value. If it’s True, the site is online. Otherwise, it’s offline, broken, down, missed…. whatever.

More about ServerXMLHTTP:

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

File Sample:

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

Enjoy!