Como en el anterior post de esta temática sobre utilizar el modulo de IIS Url Rewrite… Aquí dejo las alternativas pero ya utilizando el enrutamiento mediante los Routes, que los que trabajamos con ASP.NET MVC ya estamos acostumbrados y que tenemos desde la versión de ASP.NET 4.0 para Webforms (pero que venia ya en el SP1 de NET 3.5). Aquí dejo la introducción de utilizarlos con nuestros queridos Webforms.
Nos ayudaremos de esta configuración de enrutamiento para darle forma a los Request “enrutadas” que aceptaremos (las url) y como obtener los parámetros que vienen en dichas url (ya sea por codebehind, expresion en modo diseño o en un dataBinding) como asi también como escribir las url enrutadas vía código.
¿Que necesitamos mapear?
Lo que se requiere es poder mapear por ejemplo esta URL (un poco extensa)
http://localhost/PruebaLandingVuelo.aspx?promocion=santiago-scl-buenosaires-bue-01_10_2013-05_12_2013
A algo mucho mas amigable
http://localhost/vuelo/santiago-scl/buenosaires-bue/01_10_2013/05_12_2013
O sea lo que queremos hacer es direccionar la petición (request) a un archivo que no existe físicamente! o sea no se tiene el archivo físico que controla el request…. es decir nuestro querido webform (ni handler)!
Tenemos algunas alternativas (para incluso para Webforms…)
- El modulo del IIS Url Rewrite
Muy fácil y transparente para la app web… cualquiera sea no necesariamente ASP.NET
http://www.iis.net/downloads/microsoft/url-rewrite
Que ya escribí el anterior post: - También existen la posibilidad de redireccionar mediante HttpContext.RewritePath
(lo bueno que lo tenemos desde la versión de ASP.NET 2.0)
http://msdn.microsoft.com/es-es/library/system.web.httpcontext.rewritepath.aspx - Pero desde la versión de ASP.NET 4.0 tenemos el Enrutamiento/Routes (idem a los que utilizamos en MVC)
Que es el tema del presente post..
¿Como lo hacemos en Webforms el Enrutamiento… las rutas?
Para eso tenemos que realizar estos pasos
- Agregando Rutas con RouteCollection.MapPageRoute
- NOTA 1.1: Valores predeterminados en los parámetros de las rutas
- NOTA 1.2: Números variables de segmentos en la url o enviar parámetros con el carácter / con el comodín *
- NOTA 1.3: Restricciones a las rutas
- Recuperando valores de la pagina enrutada
- Por Codebehind: Utilizando la propiedad Page.RouteData
- En Modo diseño: Utilizando en las propiedades de los controles con la expresión RouteValue (Text="<%$RouteValue:nombre%>" )
- En los controles que soportan el DataBinding, utilizando RouteParameter
- A tener en cuenta al momento de crear enlaces de url enrutadas! Crear hipervinculos
- Creando el hipervínculo manualmente (lo que siempre nos tentamos a hacer)
- Creando automáticamente en modo diseño: Dejando que ASP.NET genere la ruta que se ajustas a los paremetros pasados en la expresion RouteUrl
- Creando desde codebehind: Utilizando RouteValueDictionary y el método RouteCollection.GetVirtualPath
PASO 1: Agregando Rutas con RouteCollection.MapPageRoute
Para agregar las rutas nos valemos del metodo RouteCollection.MapPageRoute que tiene esta forma
public Route MapPageRoute(
string routeName,
string routeUrl,
string physicalFile
)
(NOTA: Agrego el namespaces completo de RouteTables)
NOTA 1.1: Valores predeterminados en los parámetros de las rutas
Aquí ya tendremos que utilizar la sobrecarga del método MapPageRoute
public Route MapPageRoute(
string routeName,
string routeUrl,
string physicalFile,
bool checkPhysicalUrlAccess,
RouteValueDictionary defaults
)
Donde vemos que el ultimo parámetro RouteValueDictionary es un diccionario (par/valor) donde indicamos dichos valores por default.
En el ejemplo si queremos agregar un valor por default seria algo así:
En este ejemplo no es necesario los valores por default, solo a modo de ejemplificar.
NOTA 1.2: Números variables de segmentos en la url o enviar parámetros con el carácter / con el comodín *
A veces es conveniente tener varios parámetros adicionales (y no podremos escribir una ruta “dependiente de dichos parámetros”
Algo así
/vuelos/{promocion}/{param1}/…/{paramN}
Entonces la ruta la podrías escribir algo así
~/vuelos/{promocion}/{*param1}
Y allí cuando lo recuperamos vamos a tener los valores de esta manera
valor1/valor2/valor3
Por eso es útil para necesitamos que el parámetro reciba un path, url, o valor que contenga el carácter / (por lo menos es en el único lugar que lo utilice por ahora)
NOTA 1.3: Restricciones a las rutas
Podremos a las rutas además definir restricciones para definir mucho mejor el mapeo, así no se mapeara si no satisface dicha restricción… y no tendremos que hacer validaciones en nuestro código. Así que es muy útil por ejemplo cuando esperamos solo números, un formato o valores especiales, etc.
Para eso hay una sobrecarga mas de este único método MapPageRoute que soporta dicho valor de restricción, que también es un diccionario RouteValueDictionary pero en cuyo valor va una expresión regular (esa cosa que solo entienden los vulcanos, pero que es simple y potente)
Vemos que tenemos una sobrecarga:
Para el ejemplo que tenemos la url debe tener esta forma:
/vuelo/santiago-scl/buenosaires-bue/01_10_2013/05_12_2013
La expresión regular que soporta cada grupo de parámetros puede ser algo así:
- origen y destino: [a-z]*-[a-z]{3}
- fechas de salida y regreso: [0-9]{2}_[0-9]{2}_[0-9]{4}
NOTA: En el anterior post hay una expresión regular mas “exacta”. Dale una mirada…
Entonces nos quedaría la ruta con la restricción
A tener en cuenta
Este mapeo de ruta no funcionara…
- Si el archivo físico se encuentra físicamente, no se mapeara la ruta.
Salvo que se habilite la propiedad RouteExistingFiles - Si se deshabilita algunas rutas mediante la collecion RouteCollection.Ignore
Paso 2: Recuperando valores de la pagina enrutada
Para obtener los valores de los parámetros
- En el Codebehind…
Dentro de nuestro codebehind tendremos que acceder a la propiedad Page.RouteData que tiene una colección de Values
Ejemplo:
var promocion = Page.RouteData.Values["promocion"].ToString();
- En modo diseño podemos enlazar directamente una propiedad al valor mediante la expresión $RouteValue
<asp:Literal ID="litPromocionConExpresion"
runat="server"
Text="<%$RouteValue:promocion%>" />
- Y tenemos en los controles que soportan binding/enlace la posibilidad de enlazar directamente al valor RouteParameter
Algo así
...
<SelectParameters>
<asp:RouteParameter DefaultValue="ValorPorDefault" Name="promocion" RouteKey="promocion" />
</SelectParameters>
...
Paso 3: A tener en cuenta al momento de crear enlaces de url enrutadas! Crear hipervínculos
Aquí tienes dos opciones… o generamos la url manualmente (la que creamos en la ruta) o dejamos que ASP.NET genere por nosotros la ruta que se ajusta a los parámetros que pasamos. Veamos
- Generar un Hipervínculo manualmente (conociendo la ruta)
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="~/vuelo/santiago-scl-buenosaires-bue-01_10_2013-05_12_2013">
Vuelo de Santiago a Bs As para el dia 01/10/2013 al 05/12/2013
</asp:HyperLink>Aqui es obvio que tambien podremos utilizarlo sin el webcontrol Hyperlink… pero no es recomendable porque no podremos mantener este tipo de enlaces en todo nuestra aplicación web.
- Creando automáticamente en modo diseño: Dejar que ASP.NET genere el enlace.. pasando los valores de los parametros
Aqui nos aydamos de la expresion RouteUrl…<asp:HyperLink ID="HyperLink2" runat="server"
NavigateUrl="<%$RouteUrl:origen=santiago-scl,destino=buenosaires-bue,fechaSalida=01_10_2013,fechaRegreso=05_12_2013%>">
Vuelo de Santiago a Bs As para el dia 01/10/2013 al 05/12/2013
</asp:HyperLink>Aquí es mucho mas fácil mantener los enlaces a nuestras rutas.
-
Creando desde codebehind:
Aquí nos valemos de RouteValueDictionary y el método RouteCollection.GetVirtualPath
Espero que sirva de ayuda o guía