2009-07-10 19 views
13

necesito para implementar un sitio MVC con las direcciones URL por abajo:ASP.net MVC controlador de ruta personalizada/restricción

  • categoría1/producto/1/wiki
  • categoría1/producto/2/wiki
  • categoría1/sub-categoría2/producto/3/wiki
  • categoría1/sub-categoría2/sub-Categoría3/producto/4/wiki
  • etc. etc.

donde el criterio de coincidencia es que la url termina con "wiki".

Por desgracia, el cajón de sastre de abajo funciona sólo en la última parte de la url:

routes.MapRoute("page1", // Route name 
       "{*path}/wiki", // URL with parameters 
       new { controller = "Wiki", action = "page", version = "" } // Parameter defaults 

No he tenido el tiempo para ir a través de las opciones de extensibilidad MVC así que me preguntaba ¿cuáles son las opciones posibles para implementando esto? ¡Cualquier muestra/ejemplo sería simplemente fantástico!

Respuesta

15

Como mencionaste, el parámetro catch-all solo puede aparecer al final de una ruta; el código que has publicado arrojará un error en tiempo de ejecución y te mostrará la pantalla amarilla de la muerte si intentas ejecutar su aplicación.

Existen varios puntos de extensibilidad para crear escenarios de enrutamiento personalizados. Estos son: Route, RouteBase e IRouteHandler.

Puede crear una lista de rutas generadas para manejar extendiendo RouteBase. Normalmente, usted seguiría el patrón de tener un constructor que tomara un recurso (nombre del controlador), y luego le asignara una lista de las rutas de las que era responsable, y luego lo mapeara en su archivo global.asax. Aquí es un código de ejemplo se puede construir a partir de:

public class MyRoute : RouteBase 
{ 
    private List<Route> _routes = new List<Route>(); 

    public MyRoute(string resource) 
    { 
     // make a Resource property, not shown in this example 
     this.Resource = resource; 

     // Generate all your routes here 
     _routes.Add(
      new Route("some/url/{param1}", 
      new McvRouteHandler { 
       Defaults = new RouteValueDictionary(new { 
        controller = resource, 
        action = actionName 
       }), 
      Constraints = new RouteValueDictionary() 
     ); 
     _routes.Add(...); // another new route 
    } 

    public override RouteData GetRouteData(HttpContextBase context) 
    { 
     foreach (var route in _routes) 
     { 
      var data = route.GetRouteData(context); 
      if (data != null) 
      { 
       return data; 
      } 
     } 
     return null; 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext context, RouteValueDictionary rvd) 
    { 
     foreach (var route in _routes) 
     { 
      var path = route.GetVirtualPath(context, rvd); 
      if (path != null) 
      { 
       return path; 
      } 
     } 
     return null; 
    } 
} 

Para utilizar la clase de enrutamiento, hacer un routes.Add(new MyRoute("page1")); en su Global.asax.

Si necesita aún más control, puede implementar un IRouteHandler, y en lugar de crear MvcRouteHandlers() para sus rutas como se muestra en el ejemplo anterior, use su propio IRouteHandler. Esto le permitiría anular la lógica de seleccionar el controlador de los datos de solicitud.

El marco completo es extremadamente extensible, pero necesitará aprender bastante para hacerlo correctamente. Te sugiero que simplemente reorganices tu URL si es posible para aprovechar el parámetro general, si puedes.

+1

Elastic.Routing (https://github.com/lokiworld/Elastic.Routing) amplía el enrutamiento MVC integrado y le ofrece la posibilidad de utilizar catch all en cualquier segmento de su ruta, así como de algún otro bien cosas como segmentos opcionales. – BrutalDev

Cuestiones relacionadas