El modelo de página ASP.NET 2.0

Por Microsoft

En ASP.NET 1.x, los desarrolladores podían elegir entre un modelo de código insertado y un modelo de código subyacente. El código subyacente se podía implementar mediante el atributo Src o el atributo CodeBehind de la directiva @Page. En ASP.NET 2.0, los desarrolladores siguen pudiendo elegir entre código insertado y código subyacente, pero se han realizado mejoras significativas en el modelo de código subyacente.

En ASP.NET 1.x, los desarrolladores podían elegir entre un modelo de código insertado y un modelo de código subyacente. El código subyacente se podía implementar mediante el atributo Src o el atributo CodeBehind de la directiva @Page. En ASP.NET 2.0, los desarrolladores siguen pudiendo elegir entre código insertado y código subyacente, pero se han realizado mejoras significativas en el modelo de código subyacente.

Mejoras en el modelo de código subyacente

Para comprender completamente los cambios en el modelo de código subyacente en ASP.NET 2.0, lo mejor es revisar rápidamente el modelo tal como existía en ASP.NET 1.x.

El modelo de código subyacente en ASP.NET 1.x

En ASP.NET 1.x, el modelo de código subyacente constaba de un archivo ASPX (la página de Web Forms) y un archivo de código subyacente que contenía código de programación. Los dos archivos se conectaban mediante la directiva @Page en el archivo ASPX. Cada control de la página ASPX tenía una declaración correspondiente en el archivo de código subyacente como una variable de instancia. El archivo de código subyacente también contenía código para el enlace de eventos y el código generado necesario para el diseñador de Visual Studio. Este modelo funcionaba bastante bien, pero dado que todos los elementos ASP.NET de la página ASPX requerían el código correspondiente en el archivo de código subyacente, no había ninguna separación verdadera entre el código y el contenido. Por ejemplo, si un diseñador agregaba un nuevo control de servidor a un archivo ASPX fuera del IDE de Visual Studio, la aplicación se interrumpía debido a la ausencia de una declaración para ese control en el archivo de código subyacente.

El modelo de código subyacente en ASP.NET 2.0

ASP.NET 2.0 mejora considerablemente este modelo. En ASP.NET 2.0, el código subyacente se implementa mediante las nuevas clases parciales proporcionadas en ASP.NET 2.0. La clase de código subyacente de ASP.NET 2.0 se define como una clase parcial, lo que significa que solo contiene parte de la definición de clase. La parte restante de la definición de clase la genera ASP.NET 2.0 de forma dinámica mediante la página ASPX en tiempo de ejecución o cuando se precompila el sitio web. El vínculo entre el archivo de código subyacente y la página ASPX todavía se establece mediante la directiva @ Page. Pero en lugar de usar un atributo CodeBehind o Src, ahora ASP.NET 2.0 usa el atributo CodeFile. El atributo Inherits también se usa para especificar el nombre de clase de la página.

Una directiva @ Page típica podría tener este aspecto:

<%@Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>

Una definición de clase típica en un archivo de código subyacente de ASP.NET 2.0 podría tener el siguiente aspecto:

public partial class _Default : System.Web.UI.Page

Nota:

C# y Visual Basic son los únicos lenguajes administrados que admiten actualmente clases parciales. Por lo tanto, los desarrolladores que usan J# no podrán usar el modelo de código subyacente en ASP.NET 2.0.

El nuevo modelo mejora el modelo de código subyacente porque los desarrolladores ahora tendrán archivos de código que solo contienen el código que han creado. También proporciona una verdadera separación entre el código y el contenido porque no hay declaraciones de variables de instancia en el archivo de código subyacente.

Nota:

Dado que la clase parcial de la página ASPX es donde tiene lugar el enlace de eventos, los desarrolladores de Visual Basic pueden obtener un ligero aumento del rendimiento mediante el uso de la palabra clave Handles en el código subyacente para enlazar eventos. C# no tiene ninguna palabra clave equivalente.

Nuevos atributos de la directiva @ Page

ASP.NET 2.0 agrega muchos atributos nuevos a la directiva @ Page. Los siguientes atributos son nuevos en ASP.NET 2.0.

Async

El atributo Async permite configurar la página para que se ejecute de forma asincrónica. Trataremos las páginas asincrónicas más adelante en este módulo.

Async Timeout

Especifica el tiempo de espera de las páginas asincrónicas. El valor predeterminado es 45 segundos.

CodeFile

El atributo CodeFile reemplaza al atributo CodeBehind en Visual Studio 2002/2003.

CodeFileBaseClass

El atributo CodeFileBaseClass se usa en los casos en los que quiere que varias páginas deriven de una sola clase base. Debido a la implementación de clases parciales en ASP.NET, sin este atributo, una clase base que use campos comunes compartidos para hacer referencia a los controles declarados en una página ASPX no funcionará correctamente porque el motor de compilación de ASP.NET creará automáticamente nuevos miembros en función de los controles de la página. Por lo tanto, si quiere tener una clase base común para dos o más páginas en ASP.NET, deberá definir la clase base en el atributo CodeFileBaseClass y, después, derivar la clase de cada página de esa clase base. El atributo CodeFile también es necesario cuando se usa este atributo.

CompilationMode

Este atributo permite establecer la propiedad CompilationMode de la página ASPX. La propiedad CompilationMode es una enumeración que contiene los valores Always, Auto y Never. El valor predeterminado es Always. El valor Auto impedirá que ASP.NET compile dinámicamente la página si es posible. La exclusión de páginas de la compilación dinámica aumenta el rendimiento. Sin embargo, si una página que se excluye contiene ese código que se debe compilar, se producirá un error cuando se examine la página.

Enable Event Validation

Este atributo especifica si se validan o no los eventos de devolución de llamada y postback. Cuando está habilitado, los argumentos para los eventos de devolución de llamada o postback se comprueban para garantizar que se originaron en el control de servidor que los representó originalmente.

Enable Theming

Este atributo especifica si se usan o no temas de ASP.NET en una página. El valor predeterminado es false. Los temas de ASP.NET se tratan en el módulo 10.

LinePragmas

Este atributo especifica si se deben agregar pragmas de línea durante la compilación. Las pragmas de línea son opciones que usan los depuradores para marcar secciones específicas del código.

MaintainScrollPositionOnPostback

Este atributo especifica si JavaScript se inserta o no en la página para mantener la posición de desplazamiento entre postbacks. Este atributo es false de forma predeterminada.

Cuando este atributo es true, ASP.NET agrega un bloque de <script> en postback similar al siguiente:

<script src="/website/WebResource.axd?d=jBAvpwrdOM_V_Xzeox989A2 &t=632653133849531250" type="text/javascript"> </script>

Tenga en cuenta que el src de este bloque de script es WebResource.axd. Este recurso no es una ruta de acceso física. Cuando se solicita este script, ASP.NET lo compila dinámicamente.

MasterPageFile

Este atributo especifica el archivo de página maestra de la página actual. La ruta de acceso puede ser relativa o absoluta. Las páginas maestras se tratan en el módulo 4.

Style Sheet Theme

Este atributo permite invalidar las propiedades de apariencia de la interfaz de usuario definidas por un tema de ASP.NET 2.0. Los temas se tratan en el módulo 10.

Theme Value

Especifica el tema de la página. Si no se especifica un valor para el atributo StyleSheetTheme, el atributo Theme reemplaza todos los estilos aplicados a los controles de la página.

Title Value

Establece el título de la página. El valor especificado aquí aparecerá en el elemento <title> de la página representada.

ViewStateEncryptionMode

Establece el valor de la enumeración ViewStateEncryptionMode. Los valores disponibles son Always, Auto y Never. El valor predeterminado es Auto. Cuando este atributo se establece en el valor Auto, la propiedad viewstate se cifra si un control lo solicita llamando al método RegisterRequiresViewStateEncryption.

Establecimiento de los valores de propiedades públicas mediante la directiva @ Page

Otra nueva funcionalidad de la directiva @ Page en ASP.NET 2.0 es la capacidad de establecer el valor inicial de las propiedades públicas de una clase base. Supongamos, por ejemplo, que tiene una propiedad pública denominada SomeText en la clase base y quiere que se inicialice con Hello cuando se cargue una página. Para ello, basta con establecer el valor en la directiva @ Page de la siguiente manera:

<%@Page Language="C#" SomeText="Hello!" Inherits="PageBase" %>

El atributo SomeText de la directiva @ Page establece el valor inicial de la propiedad SomeText en la clase base en Hello!. El vídeo siguiente es un tutorial sobre cómo establecer el valor inicial de una propiedad pública en una clase base mediante la directiva @ Page.

Screenshot of the Microsoft Visual Studio window with a red arrow indicating a Some Text attribute on one of the lines.

Abrir vídeo en pantalla completa

Nuevas propiedades públicas de la clase Page

Las siguientes propiedades públicas son nuevas en ASP.NET 2.0.

AppRelativeTemplateSourceDirectory

Devuelve la ruta de acceso relativa a la aplicación de la página o el control. Por ejemplo, para una página ubicada en http://app/folder/page.aspx, la propiedad devuelve ~/folder/.

AppRelativeVirtualPath

Devuelve la ruta de acceso del directorio virtual relativa de la página o el control. Por ejemplo, para una página ubicada en http://app/folder/page.aspx, la propiedad devuelve ~/folder/page.aspx.

AsyncTimeout

Obtiene o establece el tiempo de espera usado para el control de páginas asincrónicas. (Las páginas asincrónicas se tratarán más adelante en este módulo).

ClientQueryString

Una propiedad de solo lectura que devuelve la parte de la cadena de consulta de la dirección URL solicitada. Este valor tiene codificación URL. Puede usar el método UrlDecode de la clase HttpServerUtility para descodificarlo.

ClientScript

Esta propiedad devuelve un objeto ClientScriptManager que se puede usar para administrar la emisión del script del lado cliente de ASP.NET. (La clase ClientScriptManager se trata más adelante en este módulo).

EnableEventValidation

Esta propiedad controla si la validación de eventos está habilitada para eventos de postback y devolución de llamada. Cuando está habilitada, los argumentos para los eventos de devolución de llamada o postback se comprueban para garantizar que se originaron en el control de servidor que los representó originalmente.

EnableTheming

Esta propiedad obtiene o establece un valor booleano que especifica si se aplica o no un tema de ASP.NET 2.0 a la página.

Formulario

Esta propiedad devuelve el formulario HTML en la página ASPX como un objeto HtmlForm.

Esta propiedad devuelve una referencia a un objeto HtmlHead que contiene el encabezado de página. Puede usar el objeto HtmlHead devuelto para obtener o establecer hojas de estilos, etiquetas meta, etc.

IdSeparator

Esta propiedad de solo lectura obtiene el carácter que se usa para separar los identificadores de control cuando ASP.NET crea un identificador único para los controles de una página. No debe usarse directamente desde el código.

IsAsync

Esta propiedad admite páginas asincrónicas. Las páginas asincrónicas se describen más adelante en este módulo.

IsCallback

Esta propiedad de solo lectura devuelve true si la página es el resultado de una devolución de llamada. Las devoluciones de llamada se describen más adelante en este módulo.

IsCrossPagePostBack

Esta propiedad de solo lectura devuelve true si la página forma parte de un postback entre páginas. Los postbacks entre páginas se tratan más adelante en este módulo.

Elementos

Devuelve una referencia a una instancia de IDictionary que contiene todos los objetos almacenados en el contexto de la página. Puede agregar elementos a este objeto IDictionary y estarán disponibles durante toda la duración del contexto.

MaintainScrollPositionOnPostBack

Esta propiedad controla si ASP.NET emite o no JavaScript que mantiene la posición de desplazamiento de las páginas en el explorador después de que se produzca un postback. (Los detalles de esta propiedad se han tratado anteriormente en este módulo).

Master

Esta propiedad de solo lectura devuelve una referencia a la instancia de MasterPage de una página a la que se ha aplicado una página maestra.

MasterPageFile

Obtiene o establece el nombre de archivo de la página maestra de la página. Esta propiedad solo se puede establecer en el método PreInit.

MaxPageStateFieldLength

Esta propiedad obtiene o establece la longitud máxima para el estado de las páginas en bytes. Si la propiedad se establece en un número positivo, el estado de visualización de las páginas se dividirá en varios campos ocultos para que no supere el número de bytes especificados. Si la propiedad es un número negativo, el estado de visualización no se dividirá.

PageAdapter

Devuelve una referencia al objeto PageAdapter que modifica la página del explorador que realiza la solicitud.

PreviousPage

Devuelve una referencia a la página anterior para un método Server.Transfer o un postback entre páginas.

SkinID

Especifica la máscara de ASP.NET 2.0 que se va a aplicar a la página.

StyleSheetTheme

Esta propiedad obtiene o establece la hoja de estilos que se aplica a una página.

TemplateControl

Devuelve una referencia al control contenedor de la página.

Tema

Obtiene o establece el nombre del tema de ASP.NET 2.0 aplicado a la página. Este valor debe establecerse antes del método PreInit.

Título

Esta propiedad obtiene o establece el título de la página tal y como se obtiene del encabezado de la página.

ViewStateEncryptionMode

Obtiene o establece el valor de ViewStateEncryptionMode de la página. Se ha proporcionado una explicación detallada de esta propiedad anteriormente en este módulo.

Nuevas propiedades protegidas de la clase Page

A continuación se enumeran las nuevas propiedades protegidas de la clase Page en ASP.NET 2.0.

Adaptador

Devuelve una referencia al objeto ControlAdapter que representa la página en el dispositivo que la solicita.

AsyncMode

Esta propiedad indica si la página se procesa de forma asincrónica. Está diseñada para su uso en el runtime y no directamente en el código.

ClientIDSeparator

Esta propiedad devuelve el carácter usado como separador al crear id. de cliente únicos para los controles. Está diseñada para su uso en el runtime y no directamente en el código.

PageStatePersister

Esta propiedad devuelve el objeto PageStatePersister de la página. Esta propiedad la usan principalmente los desarrolladores de controles ASP.NET.

UniqueFilePathSuffix

Esta propiedad devuelve un sufijo único que se anexa a la ruta de acceso del archivo para los exploradores con almacenamiento en caché. El valor predeterminado es __ufps= y un número de 6 dígitos.

Nuevos métodos públicos para la clase Page

Los siguientes métodos públicos son nuevos en la clase Page de ASP.NET 2.0.

AddOnPreRenderCompleteAsync

Este método registra delegados del controlador de eventos para la ejecución de páginas asincrónicas. Las páginas asincrónicas se describen más adelante en este módulo.

ApplyStyleSheetSkin

Aplica las propiedades de una hoja de estilos de página a la página.

ExecuteRegisteredAsyncTasks

Este método inicia una tarea asincrónica.

GetValidators

Devuelve una colección de validadores para el grupo de validación especificado, o el grupo de validación predeterminado si no se especifica ninguno.

RegisterAsyncTask

Este método registra una nueva tarea asincrónica. Las páginas asincrónicas se tratan más adelante en este módulo.

RegisterRequiresControlState

Este método indica a ASP.NET que el estado del control de las páginas debe conservarse.

RegisterRequiresViewStateEncryption

Este método indica a ASP.NET que la propiedad viewstate de las páginas requiere cifrado.

ResolveClientUrl

Devuelve una URL relativa que se puede usar para las solicitudes de cliente de imágenes, etc.

SetFocus

Este método establecerá el foco en el control especificado cuando se cargue inicialmente la página.

UnregisterRequiresControlState

Este método anulará el registro del control que se le pasa como que ya no requiere persistencia del estado del control.

Cambios en el ciclo de vida de la página

El ciclo de vida de la página en ASP.NET 2.0 no ha cambiado drásticamente, pero hay algunos métodos nuevos que debe tener en cuenta. A continuación se describe el ciclo de vida de una página ASP.NET 2.0.

PreInit (nuevo en ASP.NET 2.0)

El evento PreInit es la primera fase del ciclo de vida al que un desarrollador puede acceder. La adición de este evento permite cambiar mediante programación temas de ASP.NET 2.0, páginas maestras, propiedades de acceso para un perfil de ASP.NET 2.0, etc. Si está en un estado de postback, es importante tener en cuenta que la propiedad Viewstate aún no se ha aplicado a los controles en este punto del ciclo de vida. Por lo tanto, si un desarrollador cambia una propiedad de un control en esta fase, es probable que se sobrescriba más adelante en el ciclo de vida de las páginas.

Init

El evento Init no ha cambiado respecto a ASP.NET 1.x. Aquí es donde lee o inicializa las propiedades de los controles en la página. En esta fase, las páginas maestras, los temas, etc., ya se aplican a la página.

InitComplete (nuevo en la versión 2.0)

El evento InitComplete se llama al final de la fase de inicialización de páginas. En este punto del ciclo de vida, puede acceder a los controles de la página, pero su estado aún no se ha rellenado.

PreLoad (nuevo en la versión 2.0)

Se llama a este evento después de aplicar todos los datos de postback y justo antes de Page_Load.

Cargar

El evento Load no ha cambiado respecto a ASP.NET 1.x.

LoadComplete (nuevo en la versión 2.0)

El evento LoadComplete es el último evento de la fase de carga de las páginas. En esta fase, todos los datos de postback y viewstate se han aplicado a la página.

PreRender

Si quiere que la propiedad viewstate se mantenga correctamente para los controles que se agregan a la página dinámicamente, el evento PreRender es la última oportunidad que tiene de agregarlos.

PreRenderComplete (nuevo en la versión 2.0)

En la fase PreRenderComplete, todos los controles se han agregado a la página y la página está lista para su representación. El evento PreRenderComplete es el último evento que se genera antes de guardar la propiedad viewstate de las páginas.

SaveStateComplete (nuevo en la versión 2.0)

El evento SaveStateComplete se llama inmediatamente después de que se haya guardado el estado del control y la propiedad viewstate de la página. Este es el último evento antes de la representación real de la página en el explorador.

Representación

El método Render no ha cambiado respecto a ASP.NET 1.x. Aquí es donde se inicializa HtmlTextWriter y se representa la página en el explorador.

Postback entre páginas en ASP.NET 2.0

En ASP.NET 1.x, se requerían postbacks para publicar en la misma página. No se permitían postbacks entre páginas. ASP.NET 2.0 agrega la capacidad de devolver a otra página mediante la interfaz IButtonControl. Cualquier control que implemente la nueva interfaz IButtonControl (Button, LinkButton y ImageButton, además de controles personalizados de terceros) puede aprovechar esta nueva funcionalidad mediante el uso del atributo PostBackUrl. En el código siguiente se muestra un control Button que envía a una segunda página.

<asp:Button ID="SubmitReport" PostBackUrl="~/Default.aspx" runat="server" Text="Submit Report" />

Cuando se devuelve la página, se puede acceder a la página que inicia el postback por medio de la propiedad PreviousPage en la segunda página. Esta funcionalidad se implementa mediante la nueva función del lado cliente WebForm_DoPostBackWithOptions que ASP.NET 2.0 representa en la página cuando un control envía a otra página. El nuevo controlador WebResource.axd proporciona esta función de JavaScript que emite el script al cliente.

El vídeo siguiente es un tutorial de un postback entre páginas.

Screenshot of a video walkthrough of a cross-page postback, showing an Internet Explorer browser page displaying a Submit Report option.

Abrir vídeo en pantalla completa

Más detalles sobre los postbacks entre páginas

Viewstate

Es posible que se pregunte qué sucede con la propiedad viewstate de la primera página en un escenario de postback entre páginas. Después de todo, cualquier control que no implemente IPostBackDataHandler conservará su estado mediante la propiedad viewstate. Por lo tanto, para tener acceso a las propiedades de ese control en la segunda página de un postback entre páginas, debe tener acceso a la propiedad viewstate de la página. ASP.NET 2.0 aborda este escenario mediante un nuevo campo oculto en la segunda página denominado __PREVIOUSPAGE. El campo de formulario __PREVIOUSPAGE contiene el viewstate de la primera página para que pueda tener acceso a las propiedades de todos los controles en la segunda página.

Circumventing FindControl

En el tutorial en vídeo de un postback entre páginas, he usado el método FindControl para obtener una referencia al control TextBox de la primera página. Este método funciona bien para ese propósito, pero es costoso y requiere escribir código adicional. Afortunadamente, ASP.NET 2.0 proporciona una alternativa a FindControl para este propósito que funcionará en muchos escenarios. La directiva PreviousPageType permite tener una referencia fuertemente tipada a la página anterior mediante el atributo TypeName o VirtualPath. El atributo TypeName permite especificar el tipo de la página anterior, mientras que el atributo VirtualPath permite hacer referencia a la página anterior mediante una ruta de acceso virtual. Después de establecer la directiva PreviousPageType, debe exponer los controles, etc., a los que quiere conceder acceso mediante propiedades públicas.

Laboratorio 1: postback entre páginas

En este laboratorio, creará una aplicación que usa la nueva funcionalidad de postback entre páginas ASP.NET 2.0.

  1. Abra Visual Studio 2005 y cree un nuevo sitio web de ASP.NET.

  2. Agregue una nueva página de Web Forms denominada page2.aspx.

  3. Abra el archivo Default.aspx en la vista Diseño y agregue un control Button y un control TextBox.

    1. Asigne al control Button un identificador SubmitButton y al control TextBox un identificador UserName.
    2. Establezca la propiedad PostBackUrl de Button en page2.aspx.
  4. Abra page2.aspx en la vista Código fuente.

  5. Agregue una directiva @ PreviousPageType como se muestra a continuación:

  6. Agregue el código siguiente a Page_Load en el código subyacente de page2.aspx:

    Response.Write(PreviousPage.UserName.Text);
    
  7. Compile el proyecto haciendo clic en Compilar en el menú Compilar.

  8. Agregue el código siguiente al código subyacente para Default.aspx:

    public TextBox txtUserName {
        get { return this.UserName; }
    }
    
  9. Cambie Page_Load en page2.aspx a lo siguiente:

    Response.Write(PreviousPage.txtUserName.Text);
    
  10. Compile el proyecto.

  11. Ejecute el proyecto.

  12. Escriba su nombre en el cuadro de texto y haga clic en el botón.

  13. ¿Cuál es el resultado?

Páginas asincrónicas en ASP.NET 2.0

Muchos problemas de contención en ASP.NET se deben a la latencia de las llamadas externas (como las llamadas a servicios web o bases de datos), la latencia de E/S de archivos, etc. Cuando se realiza una solicitud en una aplicación ASP.NET, ASP.NET usa uno de sus subprocesos de trabajo para atender esa solicitud. Esa solicitud posee ese subproceso hasta que se complete la solicitud y se envíe la respuesta. ASP.NET 2.0 busca resolver problemas de latencia con estos tipos de problemas agregando la capacidad de ejecutar páginas de forma asincrónica. Esto significa que un subproceso de trabajo puede iniciar la solicitud y, después, entregar la ejecución adicional a otro subproceso, volviendo de este modo al grupo de subprocesos disponible rápidamente. Cuando se ha completado la E/S de archivos, la llamada a la base de datos, etc., se obtiene un nuevo subproceso del grupo de subprocesos para finalizar la solicitud.

El primer paso para que una página se ejecute de forma asincrónica es establecer el atributo Async de la directiva de la página de la siguiente manera:

<%@ Page Async="true" %>

Este atributo indica a ASP.NET que implemente IHttpAsyncHandler para la página.

El siguiente paso consiste en llamar al método AddOnPreRenderCompleteAsync en un punto del ciclo de vida de la página antes de PreRender. (Normalmente, se llama a este método en Page_Load). El método AddOnPreRenderCompleteAsync toma dos parámetros: BeginEventHandler y EndEventHandler. BeginEventHandler devuelve un elemento IAsyncResult que se pasa como parámetro a EndEventHandler.

El siguiente vídeo es un tutorial de una solicitud de página asincrónica.

Screenshot of the video walkthrough of an asynchronous page request, showing the Microsoft Visual Code screen.

Abrir vídeo en pantalla completa

Nota:

Una página asincrónica no se representa en el explorador hasta que no se ha completado EndEventHandler. Algunos desarrolladores consideran las solicitudes asincrónicas similares a las devoluciones de llamada asincrónicas. Es importante darse cuenta de que no lo son. La ventaja de las solicitudes asincrónicas es que el primer subproceso de trabajo se puede devolver al grupo de subprocesos para atender nuevas solicitudes, lo que reduce la contención al estar enlazado a E/S, etc.

Devoluciones de llamada de script en ASP.NET 2.0

Los desarrolladores web siempre han buscado formas de evitar el parpadeo asociado a una devolución de llamada. En ASP.NET 1.x, SmartNavigation era el método más común para evitar parpadeo, pero SmartNavigation causaba problemas para algunos desarrolladores debido a la complejidad de su implementación en el cliente. ASP.NET 2.0 soluciona este problema con devoluciones de llamada de script. Las devoluciones de llamada de script usan XMLHttp para realizar solicitudes en el servidor web a través de JavaScript. La solicitud XMLHttp devuelve datos XML que se pueden manipular mediante el DOM del explorador. El nuevo controlador WebResource.axd oculta el código XMLHttp al usuario.

Hay varios pasos necesarios para configurar una devolución de llamada de script en ASP.NET 2.0.

Paso 1: Implementación de la interfaz ICallbackEventHandler

Para que ASP.NET reconozca la página como participante en una devolución de llamada de script, debe implementar la interfaz ICallbackEventHandler. Puede hacerlo en el archivo de código subyacente de este modo:

public partial class _Default : System.Web.UI.Page, ICallbackEventHandler

También puede hacerlo mediante la directiva @ Implements de la siguiente manera:

<%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>

Normalmente, usará la directiva @ Implements al usar código ASP.NET insertado.

Paso 2: Llamada a GetCallbackEventReference

Como se ha mencionado anteriormente, la llamada XMLHttp se encapsula en el controlador WebResource.axd. Cuando se representa la página, ASP.NET agrega una llamada a WebForm_DoCallback, un script de cliente proporcionado por WebResource.axd. La función WebForm_DoCallback reemplaza la función __doPostBack para una devolución de llamada. Recuerde que __doPostBack envía el formulario en la página mediante programación. En un escenario de devolución de llamada, quiere evitar un postback, por lo que __doPostBack no será suficiente.

Nota:

__doPostBack todavía se representa en la página en un escenario de devolución de llamada de script de cliente. Sin embargo, no se usa para la devolución de llamada.

Los argumentos de la función WebForm_DoCallback del lado cliente se proporcionan mediante la función GetCallbackEventReference del lado servidor, a la que normalmente se llamaría en Page_Load. Una llamada típica a GetCallbackEventReference podría tener el siguiente aspecto:

// Set up the JavaScript callback string cbRef = cm.GetCallbackEventReference(this, "document.getElementById('ddlCompany').value", "ShowCompanyName", "null", true);

Nota:

En este caso, cm es una instancia de ClientScriptManager. La clase ClientScriptManager se trata más adelante en este módulo.

Hay varias versiones sobrecargadas de GetCallbackEventReference. En este caso, los argumentos son los siguientes:

this

Una referencia al control en el que se llama a GetCallbackEventReference. En este caso, es la propia página.

document.getElementById('ddlCompany').value

Un argumento de cadena que se pasará del código del lado cliente al evento del lado servidor. En este caso, se pasa el valor de una lista desplegable denominada ddlCompany.

ShowCompanyName

El nombre de la función del lado cliente que aceptará el valor devuelto (como cadena) del evento de devolución de llamada del lado servidor. Solo se llamará a esta función cuando la devolución de llamada del lado servidor se realice correctamente. Por lo tanto, por motivos de solidez, generalmente se recomienda usar la versión sobrecargada de GetCallbackEventReference que toma un argumento de cadena adicional para especificar el nombre de una función del lado cliente que se ejecutará en caso de error.

null

Una cadena que representa una función del lado cliente que se inició antes de la devolución de llamada al servidor. En este caso, no hay ningún script de este tipo, por lo que el argumento es null.

true

Un valor booleano que especifica si se va a realizar la devolución de llamada de forma asincrónica.

La llamada a WebForm_DoCallback en el cliente pasará estos argumentos. Por lo tanto, cuando esta página se representa en el cliente, el código tendrá el siguiente aspecto:

WebForm_DoCallback('__Page',document.getElementById('ddlCompany').value, ShowCompanyName,null,null,true)

Observe que la firma de la función en el cliente es un poco diferente. La función del lado cliente pasa 5 cadenas y un valor booleano. La cadena adicional (que es null en el ejemplo anterior) contiene la función del lado cliente que controlará los errores de la devolución de llamada del lado servidor.

Paso 3: Enlace del evento de control del lado cliente

Observe que el valor devuelto de GetCallbackEventReference en el ejemplo anterior se asignó a una variable de cadena. Esa cadena se usa para enlazar un evento del lado cliente para el control que inicia la devolución de llamada. En este ejemplo, la devolución de llamada se inicia mediante una lista desplegable de la página, por lo que quiero enlazar el evento OnChange.

Para enlazar el evento del lado cliente, basta con agregar un controlador al marcado del lado cliente de la siguiente manera:

// Hook the JavaScript function to the onchange event of the dropdown ddlCompany.Attributes["onchange"] = String.Format("javascript:{0}", cbRef);

Recuerde que cbRef es el valor devuelto de la llamada a GetCallbackEventReference. Contiene la llamada a WebForm_DoCallback que aparece más arriba.

Paso 4: Registro del script del lado cliente

Recuerde que la llamada a GetCallbackEventReference especificó que se ejecutará un script del lado cliente denominado ShowCompanyName cuando la devolución de llamada del lado servidor se realice correctamente. Ese script debe agregarse a la página mediante una instancia de ClientScriptManager. (La clase ClientScriptManager se analizará más adelante en este módulo). Puede hacerlo de la siguiente forma:

System.Text.StringBuilder clientScript = new System.Text.StringBuilder(""); ClientScriptManager cm = Page.ClientScript; // Create the client script clientScript.Append("function ShowCompanyName(companyName)"); clientScript.Append("{"); clientScript.Append("document.getElementById('CoClicked').innerHTML = \"You chose \" + companyName + \".\";"); clientScript.Append("}"); cm.RegisterClientScriptBlock(this.GetType(), "showCo", clientScript.ToString(), true);

Paso 5: Llamada a los métodos de la interfaz ICallbackEventHandler

ICallbackEventHandler contiene dos métodos que debe implementar en el código: RaiseCallbackEvent y GetCallbackEvent.

RaiseCallbackEvent toma una cadena como argumento y no devuelve nada. El argumento de cadena se pasa desde la llamada del lado cliente a WebForm_DoCallback. En este caso, ese valor es el atributo value de la lista desplegable denominada ddlCompany. El código del lado servidor debe colocarse en el método RaiseCallbackEvent. Por ejemplo, si la devolución de llamada ejecuta WebRequest en un recurso externo, ese código debe colocarse en RaiseCallbackEvent.

GetCallbackEvent es responsable de procesar el retorno de la devolución de llamada al cliente. No toma argumentos y devuelve una cadena. La cadena que devuelve se pasará como argumento a la función del lado cliente, en este caso ShowCompanyName.

Una vez completados los pasos anteriores, estará listo para realizar una devolución de llamada de script en ASP.NET 2.0.

Screenshot of the video walkthrough of performing the script callback in A S P dot NET 2 point 0. The Microsoft dropdown is highlighted.

Abrir vídeo en pantalla completa

Las devoluciones de llamada de script en ASP.NET se admiten en cualquier explorador que permita realizar llamadas XMLHttp. Esto incluye todos los exploradores modernos que se usan hoy en día. Internet Explorer usa el objeto XMLHttp ActiveX, mientras que otros exploradores modernos (incluido el próximo IE 7) usan un objeto XMLHttp intrínseco. Para determinar mediante programación si un explorador admite devoluciones de llamada, puede usar la propiedad Request.Browser.SupportCallback. Esta propiedad devolverá true si el cliente que realiza la solicitud admite devoluciones de llamada de script.

Uso de scripts de cliente en ASP.NET 2.0

Los scripts de cliente de ASP.NET 2.0 se administran mediante la clase ClientScriptManager. La clase ClientScriptManager realiza un seguimiento de los scripts de cliente usando un tipo y un nombre. Esto impide que el mismo script se inserte mediante programación en una página más de una vez.

Nota:

Después de que un script se haya registrado correctamente en una página, cualquier intento posterior de registrar el mismo script simplemente dará como resultado que el script no se registre una segunda vez. No se agregan scripts duplicados y no se produce ninguna excepción. Para evitar cálculos innecesarios, hay métodos que puede usar para determinar si un script ya está registrado y así no intentar registrarlo más de una vez.

Todos los desarrolladores de ASP.NET actuales deberían estar familiarizados con los métodos de la clase ClientScriptManager:

RegisterClientScriptBlock

Este método agrega un script en la parte superior de la página representada. Esto resulta útil para agregar funciones a las que se llamará explícitamente en el cliente.

Hay dos versiones sobrecargadas de este método. Tres de cada cuatro argumentos son comunes de ambos. Son:

type (string)

El argumento type identifica un tipo para el script. Por lo general, es una buena idea usar el tipo de la página (this.GetType()) para el tipo.

key (string)

El argumento key es una clave definida por el usuario para el script. Debe ser único para cada script. Si intenta agregar un script con la misma clave y el mismo tipo de un script ya agregado, no se agregará.

script (string)

El argumento script es una cadena que contiene el script real que se va a agregar. Se recomienda usar una clase StringBuilder para crear el script y, después, usar el método ToString() en StringBuilder para asignar el argumento script.

Si usa el método RegisterClientScriptBlock sobrecargado que solo toma tres argumentos, debe incluir elementos de script (<script> y </script>) en el script.

Puede optar por usar la sobrecarga de RegisterClientScriptBlock que toma un cuarto argumento. El cuarto argumento es un valor booleano que especifica si ASP.NET debe agregar elementos de script automáticamente. Si este argumento es true, el script no debe incluir explícitamente los elementos de script.

Use el método IsClientScriptBlockRegistered para determinar si ya se ha registrado un script. Esto le permite evitar un intento de volver a registrar un script que ya se ha registrado.

RegisterClientScriptInclude (nuevo en la versión 2.0)

La etiqueta RegisterClientScriptInclude crea un bloque de script que se vincula a un archivo de script externo. Tiene dos sobrecargas. Una toma una clave y una dirección URL. La segundo agrega un tercer argumento que especifica el tipo.

Por ejemplo, el código siguiente genera un bloque de script que se vincula a jsfunctions.js en la raíz de la carpeta de scripts de la aplicación:

ClientScriptManager cm = Page.ClientScript; if(!cm.IsClientScriptIncludeRegistered("jsfunc")) { cm.RegisterClientScriptInclude(this.GetType(), "jsfunc", "/scripts/jsfunctions.js"); }

Este código genera el código siguiente en la página representada:

<script src="/scripts/jsfunctions.js" type="text/javascript"></script>

Nota:

El bloque de script se representa en la parte inferior de la página.

Use el método IsClientScriptIncludeRegistered para determinar si ya se ha registrado un script. Esto le permite evitar un intento de volver a registrar un script.

RegisterStartupScript

El método RegisterStartupScript toma los mismos argumentos que el método RegisterClientScriptBlock. Un script registrado con RegisterStartupScript se ejecuta después de que se cargue la página, pero antes del evento OnLoad del lado cliente. En la versión 1.X, los scripts registrados con RegisterStartupScript se colocaban justo antes de la etiqueta de cierre </form>, mientras que los scripts registrados con RegisterClientScriptBlock se colocaban inmediatamente después de la etiqueta de apertura <form>. En ASP.NET 2.0, ambos se colocan inmediatamente antes de la etiqueta de cierre </form>.

Nota:

Si registra una función con RegisterStartupScript, esa función no se ejecutará hasta que la llame explícitamente en el código del lado cliente.

Use el método IsStartupScriptRegistered para determinar si ya se ha registrado un script y evitar un intento de volver a registrarlo.

Otros métodos ClientScriptManager

Estos son algunos otros métodos útiles de la clase ClientScriptManager.

GetCallbackEventReference Consulte las devoluciones de llamada de script más arriba en este módulo.
GetPostBackClientHyperlink Obtiene una referencia de JavaScript (javascript:<call>) que se puede usar para hacer postback desde un evento del lado cliente.
GetPostBackEventReference Obtiene una cadena que se puede usar para iniciar un postback desde el cliente.
GetWebResourceUrl Devuelve una dirección URL a un recurso insertado en un ensamblado. Debe usarse junto con RegisterClientScriptResource.
RegisterClientScriptResource Registra un recurso web con la página. Se trata de recursos insertados en un ensamblado y controlados por el nuevo controlador WebResource.axd.
RegisterHiddenField Registra un campo de formulario oculto con la página.
RegisterOnSubmitStatement Registra el código del lado cliente que se ejecuta cuando se envía el formulario HTML.