ASP.Net PageMethods: invocar código de servidor desde JavaScript

PageMethods permite invocar código del servidor desde el lado del cliente con JavaScript.

Esto permite recargar una página ASP.Net asincrónicamente, sin usar controles de servidor y reducir el VIEWSTATE.

Por ejemplo, en mi página tengo una serie de enlaces así:

<a href=’javascript:;’ onclick=’PaginaBotonY(i)’>i</a>

Al hacer click en un enlace, ejecuta la función PaginaBotonY(i), donde “i” es el número de página que quiero visitar.

PaginaBotonY contiene:

function PaginaBotonY(val) {
document.getElementById(“txtir”).value = val;
SendForm();
}

La función SendForm contiene:

function SendForm() {
var tamno = document.getElementById(“Npaginas”).value;
var elem = document.getElementById(‘txtir’).value;
if ((parseInt(elem) > parseInt(tamno)) | (parseInt(elem) < 1)) {
alert(‘El Numero de pagina a la que desea ir excede al limite’);
document.getElementById(‘txtir’).focus();
return;
}
var txtnronoticia = document.getElementById(“txtnronoticia”).value;
var cbopagina = document.forms[“form1”].cboPagina;
var cbopaginax;
var cantidad = cbopagina.length;
for (i = 0; i < cantidad; i++) {
if (cbopagina[i].selected == true) {
cbopaginax = cbopagina[i].value;
}
}
var pageviewstate = document.getElementById(“txtir”).value;
var totalesviewstate = document.getElementById(“TotalesPMx”).value;
var txtcaminopaginas = document.getElementById(“txtcaminopaginas”).value;
$get(“lblerror”).innerHTML = “”;
document.getElementById(“progress”).style.display = “inline”;
document.getElementById(“_divprogresoinferior”).style.display = “inline”;
PageMethods.CARGARPMY(txtnronoticia, cbopaginax, pageviewstate, totalesviewstate, txtcaminopaginas, OnSucceeded, OnFailed);
}

Básicamente, lee algunos valores de controles HTML y hace algunas validaciones, antes de llamar al código de servidor a través de: PageMethods.CARGARPMY

PageMethods.CARGARPMY acepta 5 parámetros, los cuales lee de los controles HTML y además tiene 2 funciones: OnSucceeded y OnFailed, las cuales se ejecutan en caso de que CARGARPMY se haya ejecutado con éxito o no, respectivamente.

La función de servidor CARGARPMY contiene lo siguiente:

<WebMethod()> Public Shared Function CARGARPMY(ByVal txtnronoticia As String, ByVal cbopagina As Integer, ByVal pageviewstate As String, ByVal totalesviewstate As String, ByVal txtcaminopaginas As String) As List(Of BEMensajeLis)
Dim loBEMensajeSelect As New List(Of BEMensajeSelec)//devuelve una lista de objetos loBEmensajeLis
Dim oBEPermisos As New BEPermisos
Dim NroPaginas As Integer

Dim lblresponser As String
Dim lblseguimiento As String
Dim lbleliminar As String

Dim IDMensaje As Integer
Dim Totales As String
Dim oBRMensaje As New BRMensaje
Dim oBEMensajeLis As BEMensajeLis
Dim loBEmensajeLis As New List(Of BEMensajeLis)
Dim oBEParametroMensaje As BEParametroMensaje
oBEPermisos = System.Web.HttpContext.Current.Session(“Permisos”)
NroPaginas = cbopagina
oBEParametroMensaje = New BEParametroMensaje
Dim pos As Integer
If (pageviewstate Is Nothing) Then
pos = 1
Else
pos = Integer.Parse(pageviewstate)
End If

With oBEParametroMensaje
.IDSECCION = 1
.IDMENSAJE = -1
.PALBRA = “”
.PAGE = pos
.PAGESIZE = NroPaginas
End With
loBEMensajeSelect = oBRMensaje.MensajeSelectv1(strConexion, oBEParametroMensaje)

oBEMensajeLis = New BEMensajeLis
oBEMensajeLis.IDMensaje = IDMensaje

….

……..

………..

oBEMensajeLis.Contenido = Contenedor
loBEmensajeLis.Add(oBEMensajeLis)

Return loBEmensajeLis

End Function

Nótese que la función CARGARPMY es un WebMethod (no olvidar referenciar Imports System.Web.Services en la página), por lo cual puede ser llamada desde JavaScript. Por otro lado, al ser WebMethod, no permite referenciar ningún control de servidor desde sí misma. Lo que sí permite es acceder a variables de sesión. Finalmente, esta función devuelve una lista de objetos, los cuales al ser enviados al cliente, son convertidos en formato JSON(JavaScript Object Notation), a fin de ser poder interpretados por JavaScript.

Ahora, para mostrar los datos del servidor en el cliente usando JavaScript, tenemos la siguiente función:

function OnSucceeded(resultado) {

//resultado es la lista de objetos en formato JSON, equivalente a loBEmensajeLis, devuelto por la función CARGARPMY.
if (resultado.length == 0) { //verificar que el resultado no sea nulo
$get(“PMWebService”).innerHTML = “No se hallaron resultados.”
return;
}
var itabla = “<table  border=’0′ width=’100%’><tr style=’background-color: #99CCFF’><td><b>Nro</b></td><td style=’text-align: center’><b>Noticia</b></td></tr>”;
var ftabla = “</table>”;
var pageviewstate = document.getElementById(“txtir”).value;
var dynhtml = “”;
var irow = “<tr bgcolor=’#F0F9FF’ onmouseover=’EncontrarAncla(this)’ >”;
var irowa = “<tr bgcolor=’#DDEEFF’  onmouseover=’EncontrarAncla(this)’>”;
var icol = “<td style=’width: 100%; text-decoration: none’ valign=’top’>”;
var icoln = “<td style=’width: 20px;font-weight:bold’ valign=’top’>”;
var fcol = “</td>”;
var frow = “</tr>”;
var px = “”;
var n = 0;
var colnum = “”;
var colcon = “”;
var rx;
var cbopagina = document.forms[“form1”].cboPagina;
var cbopaginax;
var cantidad = cbopagina.length;
for (i = 0; i < cantidad; i++) {
if (cbopagina[i].selected == true) {
cbopaginax = cbopagina[i].value;
}
}
for (var i = 0; i < resultado.length; i++) { //iterar en el resultado, una lista de objetos en formato JSON
rx = resultado[i];
n = parseInt(i) + 1 + ((parseInt(pageviewstate) – 1) * parseInt(cbopaginax));
colnum = icoln + n + fcol;
colcon = icol + rx[‘Contenido’] + fcol; //accediendo a la propiedad “Contenido” de un objeto de la lista
if ((i + 1) % 2) {
px = irow + colnum + colcon + frow;
}
else {
px = irowa + colnum + colcon + frow;
}
dynhtml = dynhtml + px
}
var total = itabla + dynhtml + ftabla;
onDOMReady(function() {
$get(“PMWebService”).innerHTML = total; //mostrar el HTML generado en un DIV llamado PMWebService

//así no necesito usar GridViews o DataLists, y no genero tanto VIEWSTATE
document.getElementById(“progress”).style.display = “none”;
document.getElementById(“_divprogresoinferior”).style.display = “none”;
})
}

En caso de error, se ejecutará la función OnFailed:

function OnFailed(error) {
document.getElementById(“progress”).style.display = “none”;
document.getElementById(“_divprogresoinferior”).style.display = “none”;
$get(“PMWebService”).innerHTML = “”; //DIV vacío
$get(“lblerror”).innerHTML = “<p>Error al consultar la base de datos. Intentelo nuevamente.</p>”; //mostrar el error
}

En mi página web, tengo lo siguiente:

<asp:ScriptManager ID=”ScriptManager1″ AsyncPostBackTimeOut=”36000″ runat=”server” EnablePageMethods=”True” />

<div id=”PMWebService” runat=”server” enableviewstate=”False”></div>

Eso es todo.

Referencias:

How to call Server Side function from Client Side Code using PageMethods in ASP.NET AJAX

PageMethods in ASP.NET AJAX

Using PageMethods and JSON in ASP.NET AJAX

http://encosia.com/why-aspnet-ajax-updatepanels-are-dangerous/#comment-63337

http://encosia.com/why-aspnet-ajax-updatepanels-are-dangerous/

http://encosia.com/why-you-should-not-place-your-whole-site-in-an-updatepanel/

http://geeks.ms/blogs/sergiotarrillo/archive/2009/02/19/143035.aspx

http://www.dotnetcurry.com/ShowArticle.aspx?ID=109&AspxAutoDetectCookieSupport=1

Comment posted by Jhonatan on Wednesday, March 21, 2012 3:09 PM

Hi Mathieu. Your method gets a JSON-serialized List of Enterprises (result) which you can iterate using JavaScript to build an HTML-table.

function CallSuccess(res, destCtrl)
{
var dest = document.getElementById(destCtrl);
var dynamichtml;
var htmlRow;
var enterpriseName;
var enterpriseCountry;
for (var i = 0; i < res.length; i++)
{
rx = res[i];
enterpriseName = “<td>” + res[‘EnterpriseName’] + “</td>”;
enterpriseCountry= “<td>” + res[‘enterpriseCountry’] + “</td>”;
htmlRow= “<tr>” + enterpriseName + enterpriseCountry + “</tr>”;
dynamichtml = dynamichtml + htmlRow
}
dest.innerHTML = dynamichtml ;
}

I did this on a heavy forum-like system. It was very efficient because I got rid off the viewstate generated by Gridviews.

You can check this post: https://jhonatantirado.wordpress.com/2010/11/07/asp-net-pagemethods-invocar-codigo-de-servidor-desde-javascript/

3 responses to this post.

  1. Posted by CCCP on 24 noviembre, 2011 at 12:57

    Hola, ineresante pero me sale pagemethods no está definido. Hice todos los pasos que dices en el artículo pero hay algún paso más que falte?

    Responder

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: