Routing y ASP.NET MVC

Cuando hablamos de URL amigables estamos pensando en una dirección donde un usuario puede interpretar, de forma relativamente clara, el punto donde se encuentra dentro de un sitio web. Por ejemplo:

http://www.sitioweb.com/index.aspx?accion=comprar&producto=impresora&modelo=f380

http://www.sitioweb.com/Comprar/Impresora/F380

Aunque la acción que van a realizar ambas es la misma, la segunda opción ofrece más ventajas de cara “al exterior” por decirlo de alguna manera. Gracias a las URL amigables o semánticas el usuario obtendrá unas direcciones más fáciles de recordar, a la par que comprensibles, y además conseguiremos mejorar la indexación de nuestro sitio web en los distintos buscadores.

Gracias ASP.NET MVC conseguimos esta adaptación de una forma, en un principio, “transparente” para el desarrollador, nada más empezar a trabajar con un proyecto de este tipo. Para comenzar, debemos situarnos en el archivo Global.asax de nuestra aplicación, donde aparecerá por defecto el método de registro de las rutas disponibles.

using System.Web.Mvc;
using System.Web.Routing;

namespace MovieManager
{
// Note: For instructions on enabling IIS6 or IIS7 classic mode,
// visit http://go.microsoft.com/?LinkId=9394801

public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Movie", action = "Index", id = "" } // Parameter defaults
);

}

protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
}

 Las rutas de la aplicación deben estar definidas justo antes de poder recibir cualquier petición. Es por ello que, de forma predeterminada, el registro de rutas se lleva a cabo en el archivo Global.asax. En él podemos observar dos métodos: RegisterRoutes y Application_Start. En RegisterRoutes es donde podemos añadir cada una de las rutas personalizadas y sus valores por defecto.

En primer lugar, se está restringiendo las peticiones con extensión .axd, como pueden ser Trace.axd, WebResource.axd, etcétera a través de routes.IgnoreRoute. En la segunda línea, aparece la llamada al método MapRoute que se utiliza para definir las rutas aceptadas. De forma automática, al generar la plantilla de ASP.NET MVC, se da de alta la ruta que aparece en estos momentos, donde podemos ver que recibe el nombre del controlador, la acción y un parámetro llamado id. Justo debajo, aparecen los valores por defecto para cada uno de ellos en el caso de no ser especificados en la petición.
Los nombres entre corchetes son parámetros, datos dinámicos que pueden ser escritos por el usuario o no. De no especificar ninguno, se utilizarán los valores por defecto descritos en la siguiente línea.

Al tener valores por defecto, la flexibilidad aumenta considerablemente y sin modificar absolutamente nada las rutas, podemos solicitar información de la siguiente manera:

Utilizando los valores por defecto:

http://www.sitio.com/

http://www.sitio.com/Movie

http://www.sitio.com/Movie/Index

Utilizando otras peticiones por GET, con valores distintos a los establecidos:

http://localhost:puerto/Movie/Edit/1

http://localhost:49312/Movie/Create

http://localhost:49312/Movie/Details/2

Pero quizás necesitamos llegar más allá o simplemente queremos que nuestras URL tengan una estructura diferente.
Supongamos que necesitamos generar una ruta donde queremos aclarar que la acción a realizar es la búsqueda por Género. Además no queremos que aparezca en dicha ruta el nombre la acción del controlador.

routes.MapRoute(
"ByGenre", // Route name
"List/Movies/Genre/{genre}", // URL with parameters
new { controller = "Movie", action = "Index", genre = (String)null } // Parameter defaults
);

En este caso, cuando solicitemos un resultado a través de List/Movies/Genre/Drama por ejemplo, aparecerán todas aquellas películas que se correspondan con el género indicado en última posición. Como ya comenté, no es necesario si quiera contemplar el nombre del controlador o el nombre real de la acción que queremos invocar ya que esa información se encuentra en los parámetros indicados más abajo.

NOTA: El orden en el cual se registran las rutas es muy importante ya que se tiene en cuenta el mismo. Si nosotros agregamos la nueva ruta para el filtrado por género después de la ruta por defecto ocurriría lo siguiente:

 

 

Por norma general, sería conveniente pensar en el registro de rutas por preferencia de aceptación: La que consideremos más importante ocupará la primera posición y en último lugar aparecerá la ruta por defecto.

Por otro lado, es posible que necesitemos restringir además los datos aceptados por nuestra ruta. Esto se consigue con la ayuda de los constraint.

routes.MapRoute(
"ByDate", // Route name
"List/Movies/Date/{date}", // URL with parameters
new { controller = "Movie", action = "Index", date = (DateTime?)null },
new { date = @"d{2}-d{2}-d{4}" } // Parameter defaults
);

Si por ejemplo intentáramos introducir un valor de tipo string, aparecería la página de error mostrada anteriormente.

Por último, debemos tener en cuenta que, para poder recuperar los valores introducidos, el nombre del parámetro definido en el archivo Global.asax debe corresponder en nombre al que recibe la acción.

public ActionResult Index(string genre, DateTime? date)
{
return View(_movieRepository.ListMovies(genre, date));
}

Facilito el proyecto para probar el ejemplo entero 😉

¡Saludos!

4 comentarios en “Routing y ASP.NET MVC”

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *