代码之家  ›  专栏  ›  技术社区  ›  Palantir

ASP.NET:未知长度的MVC路径

  •  3
  • Palantir  · 技术社区  · 15 年前

    我正在ASP.NET中为Web门户构建MVC应用程序。我已经准备了一系列控制器,并将所有不可访问的路径映射到一个页面控制器,该控制器将呈现适当的页面。

    我的默认路由工作方式如下:

    routes.MapRoute(
      "Default",
      "{level1}/{level2}/{level3}",
      new { controller = "Page", action = "Index", level1 = "home", level2 = "", level3 = "" }
          );
    

    但它的宽度是固定的,最多只能接受3个级别。此外,我还想管理附加到路径的操作,如“编辑”和“删除”。这有可能吗?

    company/about/who_we_are/staff -> Controller: Page, Action: Index, Parms: company/about/who_we_are/staff
    company/about/who_we_are/staff/edit  -> Controller: Page, Action: Edit, Parms: company/about/who_we_are/staff
    company/edit  -> Controller: Page, Action: Edit, Parms: company
    

    还是有更好的方法来模拟这个?页面的所有路径都在数据库中,因此它们会动态更改。

    3 回复  |  直到 12 年前
        1
  •  5
  •   Community CDub    8 年前

    您可以使用通配符路由:

    "{*data}"
    

    看看这个,这样: ASP.net MVC custom route handler/constraint


    简单可行的解决方案:

    (未测试,但…)

    路线:

    routes.Add(new Route
                               (
                               "{*data}",
                               new RouteValueDictionary(new {controller = "Page", action = "Index", data = ""}),
                               new PageRouteHandler()
                               )
                    );
    

    处理程序如下所示:

    public class PageRouteHandler : IRouteHandler
    {
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            return new PageHttpHandler(requestContext);
        }
    }
    
    class PageHttpHandler : MvcHandler
    {
        public PageHttpHandler(RequestContext requestContext)
            : base(requestContext)
        {
        }
    
        protected override void ProcessRequest(HttpContextBase httpContext)
        {
            IController controller = new PageController();
    
            ((Controller)controller).ActionInvoker = new PageActionInvoker();
    
            controller.Execute(RequestContext);
        }
    }
    
    class PageActionInvoker : ControllerActionInvoker
    {
        protected override ActionResult InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary<string, object> parameters)
        {
            string data = controllerContext.RouteData.GetRequiredString("data");
            string[] tokens = data.Split('/');
    
    
            int lenght = tokens.Length;
    
            if (lenght == 0)                   
                return new NotFoundResult();
    
            if (tokens[tokens.Length - 1] == "edit")
            {
                parameters["action"] = "edit";
                lenght--;
            }
    
            for (int i = 0; i < length; i++)
                parameters["level" + (i + 1).ToString()] = tokens[i];
    
            return base.InvokeActionMethod(controllerContext, actionDescriptor, parameters);
        }
    }
    
        2
  •  2
  •   Robert Koritnik    14 年前

    在URL的任何地方都有贪婪的段,可能吗?是的!

    我已经写了 GreedyRoute 类,该类支持URL中任何位置的贪婪(全部捕获)段。从你需要它到现在已经有一段时间了,但是它可能对将来的其他人有用。

    它支持以下任何模式:

    • {segment}/{segment}/{*greedy} -默认情况下已支持此功能 Route
    • {segment}/{*greedy}/{segment} - 中间贪婪
    • {*greedy}/{segment}/{segment} - 一开始就贪婪

    你可以阅读所有的细节 on my blog post 并获取代码。

        3
  •  1
  •   Arve Systad    15 年前

    据我所知,您可以使用正则表达式来表示路由的外观(参见底部代码部分 here )有了这一点,应该可以生成一个regex字符串,该字符串可以接受不确定数量的子节(“正斜杠和文本/数字组”)。然后,您可以分析应用程序中的URL字符串并检索相应的部分。

    然而,我不能一个人不花几个小时就写下这个regex字符串,所以其他人可能会在那里帮助你。:-)