viernes, 9 de abril de 2010

ASP.NET – Compartiendo datos en una peticion web – Page.Items o Context.Items

w3wp Vamos a plantear un caso:
Necesito alguna forma que me permita guardar los nombres de tres personas… esta variable deberá crearse al comienzo de la petición web… digamos que en el evento Application_BeginRequest del global.asax…
Sigamos: dicha variable deberá permitirme acceder a su valor mientras dure la petición…ya sea desde la página aspx, el control de usuario que está insertado en la página, el control personalizado que uso en la página, eventos de la aplicación, etc.
dado que estos valores sólo los necesitaré durante el ciclo de vida de esta petición… es el momento perfecto para decir: “jamás uses variables de sesión para guardar datos que sólo necesitarás durante una petición”.
Public Class Global_asax
Inherits System.Web.HttpApplication

Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim Nombres As New List(Of String)

Nombres.Add("Segundo Serrano")
Nombres.Add("Miguel Egea")
Nombres.Add("Juan Cotrina")

HttpContext.Current.Items("Nombres") = Nombres
End Sub

End Class

Como se habrán dado cuenta en el código de arriba, estoy usando HttpContext.Current.Items("Nombres") = Nombres para almacenar los nombres, y dadas las características del caso, es la forma ideal para guardar datos que sólo necesito en una petición… cuando se termine la petición, el valor se esfumará.

Pero, Uds suspicaces lectores me dirán: Dado que Page.Items también me permite acceder a valores durante el ciclo de vida de una página, no es suficiente? Y yo les diré: La diferencia radica en que Page.Items sólo es manipulable dentro del ciclo de vida de la página… no de la petición entera:

dense cuenta que estoy en el page_load de alguna página y puedo recuperar el valor de HttpContext.Current.Items("Nombres"), mientras que a la variable Page.Items recién le puedo asignar el valor de la variable Nombres estando dentro de la página o control,

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

'recuperamos los nombres previamente guardados
Dim Nombres As New List(Of String)
nombres = DirectCast(HttpContext.Current.Items("Nombres"), List(Of String))

'cargamos Page.Items con la lista de nombres
Page.Items("Page") = Nombres

End Sub

Ahora,  lo que tienen ambas en común es que si hubiera un control de usuario u control personalizado insertado en la página… esos controles también podrían recuperar la lsita de nombres tanto desde HttpContext.Current.Items como desde Page.Items …por ejemplo el siguiente código pertenece a un control de usuario, y desde allí puedo recuperar los nombres sin problemas:

Public Partial Class WebUserControl
Inherits System.Web.UI.UserControl

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack Then Return

Dim Nombres As New List(Of String)
Nombres = DirectCast(HttpContext.Current.Items("Nombres"), List(Of String))

Dim Nombres2 As New List(Of String)
Nombres2 = DirectCast(Page.Items("Page"), List(Of String))

End Sub

End Class


Y qué pasaría si quiero redireccionar mi página y trasmitir esos nombres a una nueva página?

Usando HttpContext.Items o Page.Items no puedes… porque hacer un Response.Redirect es equivalente a crear una nueva petición web… y las variables perderán su valor. A menos que uses Server.Transfer… en este caso HttpContext.Items aún mantendrá sus valores… a diferencia de Page.Items que como ya lo dije: sólo funciona para el ciclo de vida de esa página.

Espero que les sirva ;)

No hay comentarios.: