【问题标题】:ASP.net MVC custom route handler/constraintASP.net MVC 自定义路由处理程序/约束
【发布时间】:2009-07-10 03:18:02
【问题描述】:

我需要实现一个带有以下网址的 MVC 站点:

  • category1/product/1/wiki
  • category1/product/2/wiki
  • category1/sub-category2/product/3/wiki
  • category1/sub-category2/sub-category3/product/4/wiki
  • 等。等

匹配条件是 url 以“wiki”结尾。

不幸的是,以下内容仅适用于网址的最后一部分:

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

我没有时间了解 MVC 可扩展性选项,所以我想知道实现它的可能选择是什么?任何示例/示例都会很棒!

【问题讨论】:

    标签: asp.net-mvc constraints asp.net-mvc-routing


    【解决方案1】:

    正如您所提到的,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 参数。

    【讨论】:

    • Elastic.Routing (github.com/lokiworld/Elastic.Routing) 扩展了内置的 MVC 路由,让您能够在路线的任何部分使用 catch all 以及其他一些好东西,如可选部分。
    猜你喜欢
    • 2015-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多