Buscar..


Introducción

El enrutamiento es cómo ASP.NET MVC hace coincidir un URI con una acción. El módulo de enrutamiento es responsable de asignar las solicitudes entrantes del navegador a las acciones particulares del controlador MVC.

MVC 5 admite un nuevo tipo de enrutamiento, llamado enrutamiento de atributos. Como su nombre lo indica, el enrutamiento de atributos utiliza atributos para definir rutas. El enrutamiento de atributos le brinda más control sobre los URI en su aplicación web.

Enrutamiento personalizado

El enrutamiento personalizado proporciona una necesidad especializada de enrutamiento para manejar solicitudes entrantes específicas.

Para definir rutas personalizadas, tenga en cuenta que el orden de las rutas que agrega a la tabla de rutas es importante.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
    // this is an advanced custom route
    // you can define custom URL with custom parameter(s) point to certain action method
    routes.MapRoute(
    "CustomEntry", // Route name
    "Custom/{entryId}", // Route pattern
    new { controller = "Custom", action = "Entry" } // Default values for defined parameters above
    );

    // this is a basic custom route
    // any custom routes take place on top before default route
    routes.MapRoute(
    "CustomRoute", // Route name
    "Custom/{controller}/{action}/{id}", // Route pattern
    new { controller = "Custom", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
    );

    routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // Route pattern
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
    );
}

controller y action nombres de action están reservados. Por defecto, MVC asigna {controller} parte de la URL a la <controller>Controller y luego busca un método con el nombre <action> sin agregar ningún sufijo.

Aunque puede ser tentador crear una familia de rutas utilizando la plantilla {controller}/{action}/{parameter} al hacer esto usted revela la estructura de su aplicación y hace que las URL sean algo frágiles porque cambiar el nombre del controlador cambia la configuración. Ruta y rompe los enlaces guardados por el usuario.

Prefiere configuración de ruta explícita:

routes.MapRoute(
    "CustomRoute", // Route name
    "Custom/Index/{id}", // Route pattern
    new { controller = "Custom", action = nameof(CustomController.Index), id = UrlParameter.Optional }
);

(no puede usar el nameof operador para el nombre del controlador, ya que tendrá un sufijo adicional Controller ) que se debe omitir al configurar el nombre del controlador en la ruta.

Añadiendo ruta personalizada en mvc

El usuario puede agregar una ruta personalizada, asignando una URL a una acción específica en un controlador. Esto se utiliza para propósitos de optimización de motores de búsqueda y hace que las URL sean legibles.

routes.MapRoute(
  name: "AboutUsAspx", // Route name
  url: "AboutUs.aspx",  // URL with parameters
  defaults: new { controller = "Home", action = "AboutUs", id = UrlParameter.Optional }  // Parameter defaults
);

Atributo de enrutamiento en MVC

Junto con la forma clásica de definición de ruta, MVC WEB API 2 y luego MVC 5 introdujeron el Attribute routing :

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
        // This enables attribute routing and must go  before other routes are added to the routing table.
        // This makes attribute routes have higher priority
        routes.MapMvcAttributeRoutes();  
    }
}

Para rutas con el mismo prefijo dentro de un controlador, puede establecer un prefijo común para todos los métodos de acción dentro del controlador utilizando el atributo RoutePrefix .

[RoutePrefix("Custom")]
public class CustomController : Controller
{
    [Route("Index")]
    public ActionResult Index()
    {
        ...
    }
}

RoutePrefix es opcional y define la parte de la URL que tiene el prefijo de todas las acciones del controlador.

Si tiene varias rutas, puede establecer una ruta predeterminada al capturar la acción como parámetro y luego aplicarla a todo el controlador, a menos que se defina el atributo de Route específico en ciertos métodos de acción que anulan la ruta predeterminada.

[RoutePrefix("Custom")]
[Route("{action=index}")]
public class CustomController : Controller
{
    public ActionResult Index()
    {
        ...
    }

    public ActionResult Detail()
    {
        ...
    }
}

Conceptos básicos de enrutamiento

Cuando solicite la url yourSite/Home/Index través de un navegador, el módulo de enrutamiento dirigirá la solicitud al método de acción Index de la clase HomeController . ¿Cómo sabe enviar la solicitud al método específico de esta clase específica? Ahí viene la RouteTable.

Cada aplicación tiene una tabla de ruta donde almacena el patrón de ruta e información sobre dónde dirigir la solicitud. Así que cuando creas tu aplicación mvc, hay una ruta predeterminada ya registrada en la tabla de enrutamiento. Puedes ver eso en la clase RouteConfig.cs .

public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   routes.MapRoute("Default", "{controller}/{action}/{id}",
             new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}

Puedes ver que la entrada tiene un nombre y una plantilla. La plantilla es el patrón de ruta que debe verificarse cuando llega una solicitud. La plantilla predeterminada tiene Home como el valor del segmento url del controlador y el Index como el valor del segmento de acción. Eso significa que, si no pasa explícitamente un nombre y una acción del controlador en su solicitud, utilizará estos valores predeterminados. Esta es la razón por la que obtiene el mismo resultado cuando accede a su yourSite/Home/Index y su yourSite

Es posible que haya notado que tenemos un parámetro llamado id como el último segmento de nuestro patrón de ruta. Pero en los valores por defecto, especificamos que es opcional. Esa es la razón por la que no tuvimos que especificar el valor de id int url que intentamos.

Ahora, vuelva al método de acción de índice en HomeController y agregue un parámetro a ese

public ActionResult Index(int id)
{
     return View();
}

Ahora pon un punto de vista visual de estudio en este método. Ejecute su proyecto y acceda a su yourSite/Home/Index/999 en su navegador. Se alcanzará el punto de interrupción y debería poder ver que el valor 999 ahora está disponible en el parámetro id .

Creando un segundo patrón de ruta

Digamos que nos gustaría configurarlo para que se llame al mismo método de acción para un patrón de ruta diferente. Podemos hacerlo agregando una nueva definición de ruta a la tabla de rutas.

public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   
   // New custom route definition added
   routes.MapRoute("MySpecificRoute",
    "Important/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional });

   //Default catch all normal route definition
   routes.MapRoute("Default", "{controller}/{action}/{id}",
             new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}

La nueva definición que agregué tiene un patrón Important/{id} donde id es nuevamente opcional. Eso significa que cuando solicite su yourSiteName\Important o su yourSiteName\Important\888 , se enviará a la acción del Índice de HomeController.

Orden de registro de definición de ruta

El orden de registro de ruta es importante. Siempre debe registrar los patrones de ruta específicos antes de la ruta genérica predeterminada.

Ruta de todo

Supongamos que queremos tener una ruta que permita un número ilimitado de segmentos así:

Tendríamos que agregar una ruta, normalmente al final de la tabla de rutas, ya que esto probablemente detectaría todas las solicitudes, de este modo:

routes.MapRoute("Final", "Route/{*segments}",
      new { controller = "Product", action = "View" });

En el controlador, una acción que podría manejar esto, podría ser:

public void ActionResult View(string[] segments /* <- the name of the parameter must match the name of the route parameter */)
{
    // use the segments to obtain information about the product or category and produce data to the user
    // ...
}

Ruta completa para habilitar el enrutamiento del lado del cliente

Es una buena práctica codificar el estado de la aplicación de página única (SPA) en url:

my-app.com/admin-spa/users/edit/id123

Esto permite guardar y compartir el estado de la aplicación.
Cuando el usuario coloca la url en la barra de direcciones del navegador y los clics en el servidor deben ignorar la parte del cliente de la url solicitada. Si sirve su SPA como una vista Razor renderizada (resultado de la acción del controlador de llamada) en lugar de como un archivo html estático, puede usar una ruta de acceso directo:

public class AdminSpaController
{
    [Route("~/admin-spa/{clienSidePart*}")]
    ActionResult AdminSpa()
    {
        ...
    }
}

En este caso, el servidor solo devuelve SPA y luego se inicializa de acuerdo con la ruta. Este enfoque es más flexible, ya que no depende del módulo url-rewrite .

Atributo de enrutamiento en áreas

Para usar el enrutamiento de atributos en áreas, se requieren áreas de registro y las [RouteArea(...)] .

En RouteConfig.cs :

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapMvcAttributeRoutes();
        AreaRegistration.RegisterAllAreas();
    }
}

En una definición de enrutamiento de atributos de controlador de área de muestra:

[RouteArea("AreaName", AreaPrefix = "AreaName")]
[RoutePrefix("SampleAreaController")]
public class SampleAreaController : Controller
{
    [Route("Index")]
    public ActionResult Index()
    {
        return View();
    }
}

Para utilizar enlaces de Url.Action en Áreas:

@Url.Action("Index", "SampleAreaController", new { area = "AreaName" })


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow