JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Pedir una cosa y recibir otra - Parte IV: Llamadas de servidor que recrean la petición completa

Desvio2Hasta ahora con Transfer y Execute hemos visto que podemos ejecutar otras páginas del mismo tipo sin necesidad de redirección desde el lado cliente. Sin embargo un efecto secundario que tiene su uso es que, como no se regenera la petición sino que se ejecutan dentro del contexto de la petición actual, no entran en juego los controles de seguridad y otros eventos del pipeline HTTP para la segunda página. Es por ello por lo que en nuestro ejemplo se ha podido mostrar el contenido de la página "P2.aspx" a pesar de que estaba protegida.

Existe una variante de estos métodos llamada TransferRequest que permite conseguir una petición completa desde el propio servidor, sin pasar por el cliente como ocurría con Redirect.

Este método se utiliza del mismo modo que Transfer pero en este caso la segunda página pasa por todo los estadios de una petición HTTP normal, como si hubiera sido hecha desde el cliente desde el principio.

Así, si pretendemos llamar a P2.aspx con este método (página TransferRequest.aspx del ejemplo descargable), al contrario que con transfer obtendremos un código HTTP de acceso denegado, como si hubiese sido solicitada desde el cliente en primera instancia, ya que se ha ejecutado la autenticación y autorización de la URL nuevamente:

TransferRequest[2]_thumb

Fíjate como en la URL aparece todavía la página original (el usuario no se entera) pero al haber intentado transferir a P2.aspx falla exactamente igual.

Otra cosa más interesante todavía de este método es que como la petición se regenera por completo en realidad no estamos limitados a llamar a recursos del mismo tipo que el anterior, como pasaba con Transfer o Execute. Ahora podemos llamar a páginas ASPX, manejadores ASHX cualquier otro recurso como si lo estuviésemos pidiendo desde el navegador. En concreto podemos llamar a páginas o recursos creados con otras tecnologías. Es decir, que si tenemos PHP instalado podemos llamar a páginas .php o URLs con esta tecnología y obtener sus resultados. El usuario nunca lo sabrá.

En el ejemplo descargable hay una sencillísima página ASP 3.0 clásico (p2.asp) con esta línea:

 1: <%= "Hi from classic ASP!" %>

Si la llamamos desde el navegador veremos que funciona perfectamente bajo IIS Express.

Si ahora la llamamos desde una página ASPX usando el método TransferRequest veremos que se ejecuta y devuelve su resultado:

TransferRequest2[2]_thumb

Como vemos se ejecuta en el servidor la petición a un recurso de ASP clásico, pero en la lado cliente se sigue viendo la página ASPX original. ¿Mola o no?

Este método está disponible desde ASP.NET 2.0, no así en versiones anteriores, y para que funcione debemos usar Internet Information server 7.0 o superior en el modo integrado.

Existe una sobrecarga de TransferRequest que nos permite enviar nuestras propias cabeceras a la petición, por lo que sería posible simular desde el servidor una petición hecha con un determinado navegador (sólo con cambiar el User-Agent), o incorporar un determinado "referer", cabecera de seguridad, cookie, etc... Tiene muchas posibilidades.

Reescribir la ruta internamente

Un último método que nos falta por ver y que está relacionado con los anteriores es el que permite reescribir las rutas de las peticiones en el servidor, de forma que aunque se solicita un recurso en realidad por detrás se está llamando a otro.

Así, por ejemplo, el usuario puede solicitar desde el navegador una ruta amigable como esta:

www.myserver.com/products/details/Cheese

y que en realidad por detrás se esté llamando a:

www.myserver.com/internal/reports/viewProduct.aspx?Name=Cheese

que es una ruta interna mucho más fea y menos amigable con los buscadores (y los usuarios).

Existen muchas formas de conseguir esto: desde usar el módulo de reescritura de URLs compatible con mod_rewrite de Apache que tiene IIS 7.x, hasta usar el sistema de enrutado de ASP.NET MVC que ya he explicado aquí. De hecho esta última opción es la mejor en caso de que quieras crear rutas amigables. Pero ¿qué pasa cuando has cambiado de ubicación las páginas de tu sitio y quieres que los que las tengan guardadas puedan seguir accediendo a las mismas y que no se rompan los enlaces?

Pues en ese caso el uso de RewritePath es el más adecuado.

Basta con interceptar el método Application_BeginRequest de Global.asax para buscar rutas que queramos re-escribir en el servidor. En el ejemplo descargable si escribes la ruta "/alias" te envía a la página "P1.aspx":

 1: protected void Application_BeginRequest(object sender, EventArgs e)
 2: {
 3:     string cPath = HttpContext.Current.Request.Path.ToLower();
 4:     if (cPath.Contains("/alias"))
 5:         Context.RewritePath(cPath.Replace("/alias", "P1.aspx"));
 6: }

Nota: el código es muy "cutre" y sólo lo he puesto a efectos demostrativos. En una aplicación real habría que hacer una búsqueda y sustitución mucho mejores de las cadenas, usando una expresión regular.

El resultado es que escribiendo la carpeta "/alias" en el navegador obtenemos el contenido de P1.aspx, pero para el usuario es transparente:

RewritePath[2]_thumb

En este caso la intercepción se hace arriba en el pipeline de procesamiento de la petición por lo que se ejecutan los módulos correspondientes, incluyendo los encargados de la autenticación y autorización.

Existe una sobrecarga de este método que permite indicar que las rutas virtuales que hubiese en la pagina (para descargar recursos), no se cambien de base. Lo que hace por defecto es cambiarlas de modo que así, si la verdadera página que se utiliza está ubicada en otro nivel de la jerarquía de carpetas del sitio, diferente a la original, se sigan encontrando los recursos (como imágenes, CSS o scripts).

Con este último método he dado un repaso (creo que) muy completo a todas las formas que tiene ASP.NET de servir una página diferente a la que se solicita, sea este hecho explicitado o no. Cada una tiene sus ventajas y sus inconvenientes y es más apropiada que las otras para cada tipo de situación.

¡Espero que te haya resultado útil esta serie!

¡Espero que te resulte útil!

¿Te ha gustado este post? - Aprende .NET con los cursos on-line tutelados de campusMVP:
·
Preparación del examen 70-515: Desarrollo Web con .NET 4.0 (Tutelado por mi)
· Desarrollo Web con ASP.NET 4.0 Web Forms (Tutelado por mi)
· ASP.NET 4.0 Web Forms desde cero (Tutelado por mi)
· Desarrollo Web con ASP.NET MVC 3
· Silverlight 4.0 - Aplicaciones Ricas para Internet (RIA)
· jQuery paso a paso para programadores ASP.NET
· Visual Studio 2010 desde cero

>> Pedir una cosa y recibir otra

José Manuel Alarcón José Manuel Alarcón
Fundador y director de campusMVP.es, el proyecto de referencia en formación on-line para programadores en lengua española. Autor de varios libros y cientos de artículos. Galardonado como MVP de Microsoft desde 2004. Gallego de Vigo, amante de la ciencia y la tecnología, la música y la lectura. Ayudando a la gente en Internet desde 1996.
Descarga GRATIS mi último libro (no técnico): "Tres Monos, Diez Minutos".
Banner

Comentarios (2) -

Muy buena la explicación, muchas gracias .......

Sin embargo me surge una duda.

Explicaste como acceder desde una pagina referenciada a la pagina que la referencio, pero, como seria una buena forma de acceder a los objetos y demas de la referencia?; espero me haga entender.

Responder

Spain José Manuel Alarcón

No sé si te entiendo bien, pero creo que eso lo es lo que explico, con bastante detalle, en la segunda parte de esta serie:

www.jasoft.org/.../...Transferir-la-ejecucion.aspx

Saludos,

Responder

Pingbacks and trackbacks (2)+

Agregar comentario