Server.Transfer o Response.Redirect, para enviar a los usuarios a otra pagina?

Ninguno , si sólo deseamos pasar un usuario a otro página y no vamos a cambiar el destino dinámicamente solo debemos usar <a href=”http://tu_link”>tu Link</a>.


Es que, hay algo que se debe entender y debe quedar claro, no porque ahora tengamos muchos controles de servidor, debemos usarlos todos, cada uno tiene su función y si no necesitamos procesamiento o alguna acción del lado del servidor, no hay porque usarlos, recuerden que al desarrollar aplicaciones web hay consideraciones mínimas que debemos tener para que la experiencia del usuario al navegar en nuestro sitio web sea la mejor.


Ahora, que hacemos si deseamos enviar al usuario a otra página, podemos usar un link, como el mostrado arriba. Si nuestro link será dinámico, si usar un control HyperLink o si queremos asignar programáticamente nuestros links podríamos usar Response.Redirect. La idea de Server.Transfer digamos que no es un reenviar propiamente dicho, sino un reenviar y pero mantener la información de la página origen.


Pero veamos un caso, el cual nació a través de una mail que me enviaron, y que es el origen de este post:


Caso: Veras Sergio, estoy en el capitulo de los “Themes”, lo que quiero hacer es que el usuario pueda elegir en el “dropdownlist” el color de “theme” que desea aplicar a una segunda página, cuando el usuario elija el color del “theme” lo REDIRECCIONO a una segunda página que tiene unos objetos que tomaran el color del “theme”.


Los problemas que tengo:



  • Si utilizo  Server.Transfer(“pagina2.aspx”) La barra de navegación del navegador (URL)  NOOOO MUESTRA la dirección de la página,  sino que se queda con la direccion de la primera. El color del “theme” SI funciona y se aplica a los objetos.

  • Si utilizo  Response.Redirect(“pagina2.aspx”) La barra de navegación del navegador (URL)  SIIIII MUESTRA la dirección de la página,  PERO El color del “theme” NOOOOOO funciona y por lo tanto los objetos se quedan con el color por default que tienen.

Ejecute el código enviado y pues si, ocurría lo que se mencionaba, pero examinemos el código de la página origen:



Protected Sub DropDownList1_SelectedIndexChanged( )
   
Server.Transfer(“pagina1.aspx”)
   
‘Response.Redirect(“pagina1.aspx”)
End Sub


Además hay un combo que contiene los valores: Azul, Verde, y Rojo. Al seleccionar un valor del combo se muestra el contenido de la otra página, el código que usa es el siguiente:



Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs)
   Page.Theme = Request(“menucolor”)
End Sub


Efectivamente este código funciona, pero porque no funciona cuando comento el Server y descomento el Response? , misterios sin resolver?


A ver primeros examinemos porque funciona, y después porque no funciona con Response.Redirect:



  • Lo que hace un Server.Transfer, es transferir el actual contexto a una página destino, pero solo se muestra la página destino. La ventaja esta en que se puede recuperar los valores del form, y controles de la página de origen [URL01].

  • Request(“menucolor”), porqué devuelve el color?, si solo ponemos el nombre del control?. Lo que esta pasando es como si hubiera colocado un boton html submit, y hubiéramos enviado todo el form, es por eso que al hacer Request(“menucolor”), nos devuelve el valor seleccionado del control generado en html, un SELECT. Si por ejemplo agregáramos un control label y quiséramos recuperar la propiedad Text, no podríamos porque este genera una etiqueta html SPAN, en cambio con un control TextBox si se podría recuperar la propiedad Text, porque el TextBox genera un control INPUT de tipo text.

Pero como funcionaría esto, usando Response.Redirect?



  • Al usar Response.Redirect, lo que pasa es como si hubiéramos colocado un link, y hubiéramos pulsado el link [URL02], la ventaja esta en que se puede hacer programáticamente.

  • Ahora en este caso si queremos que cuando se cambie el combo se vaya a la otra página usamos Response.Redirect, en caso contrario podríamos usar un HyperLink, el cuál sería programáticamente, se cambiaría la propiedad NavigateUrl, dependiendo que seleccione en el combo, después usando el link iríamos a la otra página. Esta última opción daría como ventaja que podríamos usar las propiedades un link, como target, entre otras.

  • Vamos hacerlo directamente en el combo, enviando valores directamente por la URL:


Protected Sub DropDownList1_SelectedIndexChanged()
  
‘Server.Transfer(“pagina1.aspx”)
   
Response.Redirect(“pagina1.aspx?colortema=” + menucolor.Text)

End
Sub



  • Y para recuperar las variables en la página destino sería de la siguiente manera:


Protected Sub Page_PreInit()    
    Page.Theme = Request.QueryString(“colortema”
)
End Sub



  • Podríamos usar también directamente Request(“colortema”), pero QueryString, es más específico para variables en la URL, ya que nos puede devolver en un arreglo de strings todas las variables de la URL, o el número de variables enviadas por la URL.

  • Con Response.Redirect, la url que aparece en el navegador es la de la página destino, y no de la página origen como si es el caso con Server.Transfer.

Mas sobre Server.Transfer vs. Response.Redirect, aquí. Pero un debate interesante es el siguiente, y una definición de ellos acá.


P.D.: Pediría que si en el futuro tengan dudas, en primera instancia las envíen a los foros, muchos de los temas ya fueron tocados por otra persona en otros post, y solo es cuestión de buscar y revisar la solución. Muchas veces es difícil, para mi, contestar rápidamente los mails de consulta, en cambio en un foro, hay muchos usuarios que podrían resolver la duda, además que hay mas variedad de opiniones. Tenemos foros muy buenos en espaniol, como el del Guille: http://foros.elguille.info, y los de solocodigo: http://foros.solocodigo.com/index.php?showforum=169.


Referencias:



Saludos,


Post cruzado desde starrillo blog

Pasando variables entre paginas web ASP.NET usando Cross Page Postback

Existen varias formas de pasar variables entre formularios web, como por ejemplo haciendo uso de la URL, o usando sesiones. Cada una de estas caracteristicas tiene sus ventajaa y desventajas.

Ahora que nueva característica trajo ASP.NET 2.0?, Cross Page Postback. Pero que hace esta característica, veamos el siguiente gráfico y después damos una breve explicación [URL01]:

Antes con ASP.NET 1.X, solo se podía hacer PostBack a la misma página, es decir cuando pulsaba cualquier botón esta se dirigía hacia si misma, ahora en ASP.NET 2.0, se puede hacer Cross Page Postback, es decir ya no limitar que mi página solo pueda ser enviada a si misma, sino que puedo enviar el contenido a cualquier otra página. Las aplicaciones que se le puede dar a esta característica son varias, veamos algunas de sus ventajas:

  • Todo la información de la página actual estará disponible en la página destino.
  • Permite que la página destino acceda a las propiedades públicas de la página origen.
  • Debido a las ventajas anteriores, permite el paso de variables entre páginas.

Pero manos a la obra, como hacemos esto?, pues aquí uno de los escenarios en los cuáles se podría aplicar. Se trata de un formulario de confirmación de registro, para esto necesitamos el nombre, y los datos ingresados en la página origen, para asi mostrarla en la página destino:

Página Origen (wf_registro.aspx):

Página Destino (wf_confirmacion.aspx):

Ahora cuáles son los pasos para lograr esto?:

  • En la página wf_registro.aspx y en el botón de envio btnEnviar, modificamos la siguiente propiedad PostBackUrl (en la ventana de propiedades o desde la vista source de la página):

PostBackUrl="~/wf_confirmacion.aspx"

="~/wf_confirmacion.aspx"

  • Ahora en el evento Load de la página wf_confirmacion.aspx, agregamos el siguiente código [Cod01]:

protected void Page_Load(object sender, EventArgs e)
{
 
string nombre;
 
  TextBox
txtNombre = 
     
(
TextBox)Page.PreviousPage.FindControl("txtNombre");

nombre = txtNombre.Text;

lblConfirmacion.Text = 
  
string.Format("{0} gracias por ingresar su informacion <br/>" +
               
"USTED HA SIDO REGISTRADO", nombre);
}

protected void Page_Load(object sender, EventArgs e)
{
 
string nombre;
 
  TextBox
txtNombre = 
     
(
TextBox)Page.PreviousPage.FindControl("txtNombre");

nombre = txtNombre.Text;

lblConfirmacion.Text = 
  
string.Format("{0} gracias por ingresar su informacion <br/>" +
               
"USTED HA SIDO REGISTRADO", nombre);
}

  • Corremos y todo OK, pero creen que ahí queda todo? , pues esta funcionando, pero hay que agregar algunas validaciones.
  • Qué pasaría si accedemos directamente a wf_confirmacion.aspx, pues que daría un error, para evitar esto agregamos nuestro [Cod01], el que esta dentro del load, y lo ponemos dentro de este if:

if (Page.PreviousPage != null)
{ … }

if (Page.PreviousPage != null)
{ … }

Ahora como podemos mejorar el acceso a la página origen?, si bien el método FindControl es útil, puede no darte precisión al colocar mal el nombre. Para evitar estos incovenientes podemos hacer uso de Propiedades Públicas. Nota: Tratar de colocar solo la información necesaria en variables públicas, para reducir la cantidad de información disponible para usuarios potencialmente malintencionados .

  • Para poder acceder a las propiedades de la página origen se debe establecer una referencia "strongly type" a ella. Hay dos formas de hacerlo [URL04], pero nosotros vamos a hacer uso de la directiva @PreviousPageType, para nuestro cometido, y agregamos el siguiente código a nuestra página wf_confirmacion.aspx:

<%@ PreviousPageType VirtualPath="~/wf_registro.aspx" %>

@ PreviousPageType VirtualPath="~/wf_registro.aspx" %>

  • Agregamos la siguiente propiedad a nuestra clase wf_registro.aspx.cs:

public string NombreRegistro {
 
get {
    
return txtNombre.Text;
 
}
}

public string NombreRegistro {
 
get {
    
return txtNombre.Text;
 
}
}

  • Ahora el nuevo Load de la página wf_confirmacion.aspx, quedaría así:

protected void Page_Load(object sender, EventArgs e)
{
 
if (Page.PreviousPage != null)
 
{
   
string nombre =
     
PreviousPage.NombreRegistro;

    lblConfirmacion.Text =
     
string.Format("{0} gracias por registrarse <br/>" +
                  
"USTED HA SIDO REGISTRADO", nombre);
 
}
}

protected void Page_Load(object sender, EventArgs e)
{
 
if (Page.PreviousPage != null)
 
{
   
string nombre =
     
PreviousPage.NombreRegistro;

    lblConfirmacion.Text =
     
string.Format("{0} gracias por registrarse <br/>" +
                  
"USTED HA SIDO REGISTRADO", nombre);
 
}
}

  • Se nota la diferencia .

Ahora qué sucede si es que yo voy a llamar al página de confirmación de diversas páginas?, es decir no quiero atar la propiedad pública a una página. Pues para eso haremos uso del patrón adapter [URL03]:

  • Agregaremos esta interface a la carpeta App_Code:


using System;

public interface IRegistroForm
{
 
string NombreRegistro
 
get}
}

System;

public interface IRegistroForm
{
 
string NombreRegistro
 
get}
}

  • Ahora hacemos que nuestra clase wf_Registro implemente a IRegistreForm, además de heredar de System.Web.UI.Page:

wf_registro : System.Web.UI.Page, IRegistroForm

: System.Web.UI.Page, IRegistroForm

  • Ahora podemos remover la directiva @PreviousPageType, de la página wf_confirmacion.aspx, y actualizamos el código dentro de nuestro Load:

protected void Page_Load(object sender, EventArgs e)
{
 
if (Page.PreviousPage != null)
 
{
   
IRegistroForm form = PreviousPage as IRegistroForm;

    if (form != null)
   
{
     
string nombre =
            
form.NombreRegistro;

      lblConfirmacion.Text =
         
string.Format("{0} gracias por registrarse <br/>" +
                     
"USTED HA SIDO REGISTRADO", nombre);
   
}
 
}
}

protected void Page_Load(object sender, EventArgs e)
{
 
if (Page.PreviousPage != null)
 
{
   
IRegistroForm form = PreviousPage as IRegistroForm;

    if (form != null)
   
{
     
string nombre =
            
form.NombreRegistro;

      lblConfirmacion.Text =
         
string.Format("{0} gracias por registrarse <br/>" +
                     
"USTED HA SIDO REGISTRADO", nombre);
   
}
 
}
}

Espero que haya quedado claro el post/artículo, si tienen alguna pregunta, o algo que agregar, me dejan un comentario. En nuestro último código deberíamos hacer uso de la propiedad PreviousPage.IsCrossPagePostBack y de PreviousPage.IsValid, para una mejor validación, en las referencias de abajo podremos encontrar más detalles sobre estas propiedad, queda como tarea .

P.D.: Adjunto el archivo del post/artículo.

Referencias:

  • [URL01]: Secretos internos de ASP.NET – <link>
  • [URL02]: Redirigir a los usuarios a otra página – <link>
  • [URL03]: Design Considerations for Cross Page Post Backs in ASP.NET 2.0 – <link>
  • [URL04]: Envío entre páginas en las páginas Web ASP.NET – <link>

Saludos,

Post cruzado desde starrillo blog

Recursos C#, Csharp, articulos, tutoriales, videos, foros…

La semana pasada se inicio el "Curso de Introducción a C#" para los ingresantes 2006-I a mi universidad, Universidad Nacional de Trujillo. Por cierto es uno de los últimos cursos que creo que estaré como organizador/instructor en la Celula.Net UNT, ya que faltan pocos meses para egresar, y dedicarme completamente al trabajo . Como Instructor si continuaré hasta que me jubilen , si es que me invitan por supuesto.

Cabe resaltar que este curso está orientado a "ingresantes" a la carrera de Ing. de Sistemas, y porqué menciono esto?, porque hasta ahora es el mejor grupo que me ha tocado enseñar (aquí algunas fotos de los nuevos talentos de la Celula.Net UNT), todos aprenden parejo, por supuesto que unos más que otros, pero todos aprenden. Tratando de entender porque sucede esto, y no me paso con otros grupos, es que al parecer todavía no adoptan malas prácticas, ya sea por libros, artículos, cursos, u otra fuente de información, además que para algunos recién están adoptando un lenguaje de programación, o será porque son de la UNT . Una vez tuve la oportunidad de dictar un curso fuera de mi ciudad, a personas que ya conocían algunos otros lenguajes, y me preguntaban como hago un inputBox, lo que se hace con VB, en C#; otro de los problemas es que en algunas "facilidades" que tiene VB6.0, y quieren que también este en otro lenguaje, como el uso de variables no declaradas, la conversión de tipos, da lo mismo hacer mayúsculas que minúsculas, entre otras cosas. Y digo facilidades entre comillas, porque para algunos así lo es, y para otros pueden ser consideradas como malas practicas de programación, como por ejemplo lo es usar "hardcode" en tu código. Pero bueno, no es nada que tenga en contra de VB, pero si están empezando a programar recomendaría hacerlo en C# . Aunque, como les dije a los alumnos del curso, si aprendes "bien", mejor digamos superbien, un lenguaje se te hace más fácil aprender cualquier otro lenguaje, es decir lo que hay que aprender a cultivar es la abstracción para programar, esto es algo que no todos lo tienen .

Bueno y lo que iba, y que prometí a este "gran" grupo, recursos para aprender C#, lo vamos a clasificar en: recursos en espaniol y recursos en ingles:

Recursos en Espaniol:

Recursos en Ingles:

Ahora no tienen ninguna escusa para no aprender C# . Por cierto casi lo ovido, en este blog también cuenta con un tag de C#: <link>.

P.D. Si sabes de algunos links, que crees que deben ir, los colocan en los comentarios por favor.

Saludos,

Post cruzado desde starrillo blog

Usando CSS Controls Adapter en ASP.NET 2.0, mejora y optimiza tu presentacion

Para entender que es un control adapter y descargarlo, podemos visitar el blog de ScottGu's: CSS Control Adapter Toolkit Update. Pero un pequeño resumen es: Con un control adapter, puedes modificar la manera como se muestra tus controles de servidor ASP.NET en el navegador, por ejemplo podemos hacer que un control Menu se "renderice", se muestre, con etiquetas ul, li, y no con etiquetas table, td, tr.

En este ejemplo vamos a mostrar, que pasaría si yo tengo un Web Site, y quiero incorporar CSS Control Adapters a mi web.

  1. Primero verifiquemos la presentación actual de nuestro sitio Web, como se puede apreciar el control menú sin un control adapter: 
  2. Ahora vamos a crear un nuevo Web Site tomando como plantilla el Tutorial on CSS Friendly ASP.NET 2.0:
  3. Ahora vamos a ir copiando los archivos que necesitamos en nuestra sitio Web, primero copiaremos las clases: MenuAdapter.cs y WebControlAdapterExtender.cs:

    La clase MenuAdapter es la que generará el nuevo render del HTML generado por el control Menu.
  4. Ahora copiaremos los archivos CSS básicos, los cuales son usados en la clase MenuAdapter:
  5. Ahora agregaremos el MenuAdapter de a nuestro sitio web, usando un archivo *.browser:
  6. Ahora tenemos que copiar el archivo CSS que dará el estilo al control menú (CssSelectorClass), en el tutorial encontramos dos, yo copiaré el archivo MenuExample.css a mitema(este ya lo tenía en mi webSite):
  7. Además tengo que copiar otros archivos de imagen que usan los estilos del archivo MenuExample.css:
  8. Ahora copio un Skin para el control menú del tutorial, a mi miSkin.skin, el cual tambien usa estilos del archivo MenuExample.css:
  9. Ahora asigno el estilo de mi control menú y asigno los atributos respectivos, SkinID y CssSelectorClass, el estilo PrettyMenu, ha sido definido en MenuExample.css:
  10. Ahora ejecuto mi página Contacto.aspx, pero antes le agrego el Theme a la página Contactos.aspx, en la directiva @page:

    StylesheetTheme="miTema"

    ="miTema"

  11. Si ya lo ejecutaron se podrán dar cuenta que falto algo , para verlo correctamente, tenemos que agregar lo siguiente a nuestra master page, site.master:
  12. Ahora si ejecutemos y veamos los resultados:

Los resultados saltan a la Vista. Espero que esto les sirva como ejemplo base, para empezar a usar los control adapters del CSS Friendly ASP.NET 2.0 . Los controles disponibles son: Menu, TreeView, GridView, DetailsView, FormsView, DataList, Login, ChangePassword , CreateUser, PasswordRecovery, y LoginStatus.

Aquí se ha presentado el funcionamiento y lo ocurre detrás de todo esto, de manera sencilla, con ideas básicas que permitan entender lo que hacemos, si queremos saber más de la arquitectura podemos visitar: ASP.NET 2.0 Control Adapter Architecture.

Ustedes escogen si necesitan usar los adaptores, si ya cuentan con estilos propios, pueden no necesitan usarlo, o también puede integrar todos sus CSS al Control Adapter. Todo dependerá de su escenario .

Adjunto el Web Site, que use. Es necesario instalar, CSS Friendly ASP.NET 2.0 Control Adapters (Beta 2.0).

P.D.: Si alguién tiene un estilo por ahí, y lo integra al CSS Friendly, me pasa la voz :D.

Saludos,

Post cruzado desde starrillo blog

Gira INETA Andino 2006: Colombia, Ecuador y Peru (Lima, Huancayo, Trujillo y Cuzco)

Inscripciones

Detalles de la Gira en Trujillo

Inscripciones: http://www.inetalatam.org/giras/inscrigiras.aspx

Detalle de sesiones en Trujillo: Gira Andina en Trujillo, Perú (27 de Septiembre)

P.D.: El Guille y Willy Marrroquin en Trujillo  

P.D.2: La animación del evento, en la portada de INETA: http://www.inetalatam.org/, esta bravaza!

Saludos,

Post cruzado desde starrillo blog