2009-07-10 91 views
13

我需要实现一个MVC网站搭配以下网址:ASP.net MVC自定义路由处理程序/约束

  • 组别/产品/ 1 /维基
  • 组别/产品/ 2 /维基
  • 类别1 /子类别2 /产品/ 3 /维基
  • 类别1 /子类别2 /子类别3 /产品/ 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; 
    } 
} 

要使用你的路由类,在你的Global.asax做routes.Add(new MyRoute("page1"));

如果你需要更多的控制,你可以实现一个IRouteHandler,而不是如上例所示为你的路由创建MvcRouteHandlers(),使用你自己的IRouteHandler。这将允许您覆盖从请求数据中选择控制器的逻辑。

整个框架是非常可扩展的,但你需要学习很多才能正确地做到这一点。如果可以的话,我建议只要重新排列URL就可以利用catch-all参数。

+1

Elastic.Routing(https://github.com/lokiworld/Elastic.Routing)扩展了内置的MVC路由,并为您提供了在路由的任何部分使用catch all以及其他一些好东西东西像可选的部分。 – BrutalDev 2013-10-08 05:36:22