2009-07-10 5 views
13

мне нужно реализовать сайт MVC с URL-адресов в поле ниже:ASP.net MVC пользовательский маршрут обработчик/ограничение

  • category1/продукт/1/вики
  • category1/продукта/2/вики
  • категория1/суб-категория2/продукта/3/вики
  • категория1/суб-категория2/суб-category3/продукта/4/вики
  • и т.д. и т.п.

, где критерии соответствия заключаются в том, что URL-адрес заканчивается «wiki».

К сожалению, ниже всеохватывающий работает только в последней части URL:

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

у меня не было времени, чтобы пройти через расширяемости MVC поэтому мне было интересно, что возможные варианты для это? Любой образец/пример был бы просто фантастическим!

ответ

15

Как вы упомянули, параметр catch-all может появляться только в конце маршрута - код, который вы опубликовали, вызовет ошибку во время выполнения и даст вам желтый экран смерти, если вы даже попытаетесь запустить ваше приложение.

Существует несколько точек расширяемости для создания пользовательских маршрутных сценариев. Это - Route, RouteBase и IRouteHandler.

Вы можете создать сгенерированный список маршрутов для обработки, расширив RouteBase. Как правило, вы должны следовать шаблону наличия конструктора, который принимает ресурс (имя контроллера), а затем присваивает ему список маршрутов, за которые он отвечает, а затем сопоставляет его в вашем global.asax. Вот несколько примеров кода вы можете создать из:

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; 
    } 
} 

Чтобы использовать класс маршрутизации, сделать routes.Add(new MyRoute("page1")); в вашем Global.asax.

Если вам нужен еще больший контроль, вы можете реализовать IRouteHandler, и вместо создания MvcRouteHandlers() для ваших маршрутов, как показано в приведенном выше примере, используйте свой собственный IRouteHandler. Это позволит вам переопределить логику выбора контроллера из данных запроса.

Весь каркас чрезвычайно расширяемый, но вам нужно будет изучить немного, чтобы сделать это правильно. Я бы предложил просто переставить URL-адрес, если это возможно, чтобы воспользоваться опцией catch-all, если сможете.

+1

Elastic.Routing (https://github.com/lokiworld/Elastic.Routing) расширяет встроенную маршрутизацию MVC и предоставляет вам возможность использовать улов на любом сегменте вашего маршрута, а также некоторые другие полезные такие как необязательные сегменты. – BrutalDev

Смежные вопросы