【问题标题】:asp.NET: Unknown length MVC pathsasp.NET:未知长度的 MVC 路径
【发布时间】:2009-08-26 06:49:43
【问题描述】:

我正在为 Web 门户在 asp.NET 中构建一个 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

或者有更好的建模方法吗?页面的所有路径都在数据库中,因此它们是动态变化的。

【问题讨论】:

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


    【解决方案1】:

    您可以使用通配符路由:

    "{*data}"
    

    看看这个 SO: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);
        }
    }
    

    【讨论】:

    • 似乎它不允许以简单的方式将“编辑”操作附加到我的路径:(但这是 MVC 引擎本身的问题。也许我只会在操作之前添加操作。 ..
    【解决方案2】:

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

    我已经编写了GreedyRoute 类,它支持 URL 中任意位置的贪婪(全部捕获)段。您需要它已经有一段时间了,但它将来可能对其他人有用。

    它支持以下任何一种模式:

    • {segment}/{segment}/{*greedy} - 默认 Route 类已经支持此功能
    • {segment}/{*greedy}/{segment} - 中间贪婪
    • {*greedy}/{segment}/{segment} - 一开始很贪心

    您可以阅读所有详细信息on my blog post 并获取代码。

    【讨论】:

      【解决方案3】:

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

      但是,如果不花费数小时,我无法自己编写此正则表达式字符串,因此其他人可能会在那里为您提供帮助。 :-)

      【讨论】:

        猜你喜欢
        • 2010-11-14
        • 2015-05-10
        • 1970-01-01
        • 2016-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多