【问题标题】:Dynamic url routes ASP MVC动态 url 路由 ASP MVC
【发布时间】:2010-12-30 12:07:22
【问题描述】:

我正在尝试制作一个非常简单的应用程序,让我的客户可以创建自己的页面。 困难的部分是让他们创建自己的 URL。

客户需填写:

  • 页面名称(例如关于我们)。
  • 页面说明(例如,我们是一家大公司)。
  • 相对于页面 URL(例如 /About)

当客户端输入此信息并保存时,它应该保存在数据库中。

我可以轻松创建一个名为“Page”的控制器,该控制器接受一个值“ID”,当用户输入“www.someurl.com/Page/1”时,新创建的页面会弹出。

但我真正想要的是用户写“www.someurl.com/About”然后页面弹出。

如何通过使用 ASP MVC 的某种动态重写/路由代码来完成此操作。

【问题讨论】:

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


    【解决方案1】:

    我的想法是在您的“页面”表中创建一个名为“Slug”的字段。当您的用户创建一个新页面时,他们必须填写“Slug”字段并输入他们希望在 url 中看到的内容(例如:想要的页面 - “关于”,slug - “关于”|想要的页面 - “见我们的赞助商”,slug - “see-our-sponsors” | 等等)。如果你愿意,你可以用一点 javascript 来自动化这个过程。

    像这样创建一条路线:

    routes.MapRoute(
        null,
        {slug},
        new { controller = "Page", action = "ChoosePage" });
    

    像这样创建一个动作方法:

    [AcceptVerbs(HttpVerbs.Get)]
    public ViewResult ChoosePage(string slug)
    {
        //Logic to display page
    }
    

    基本上,它就像您将页面 id 放在 url 中的想法一样,但它会更简洁,它会使用“slug”来进行数据库查找而不是页面 id。

    【讨论】:

    • 确保将路线放置为路线页面中的最后一条路线。这样,如果用户创建的路由与您的硬编码路由冲突,您的硬编码路由将被执行,确保您的应用程序不会中断。此外,创建一个已被使用的“禁止”路由列表你的应用程序。
    • 我也将它添加到“默认”路由下方,但后来它不起作用。当我将它直接放在“默认”路线上方时它起作用了,可以吗?
    • 如果我希望用户创建自己的关卡怎么办(例如 /News/my-news-item)。该解决方案仅支持一个级别,将其扩展到“未知级别”解决方案的最佳方法是什么?
    • 是的,我认为 Baddie 忘了提到要删除标准默认路由或将其放在前面。您遇到的问题是默认路由看起来像 {controller}/{action}/{id}。它正在获取您的“/about”网址并试图找到一个名为“about”的控制器和一个导致热混乱的空操作方法。我只会删除默认路由。至于动态 url 中的级别:“my-news-item”是像博客文章一样的东西,还是像原始示例一样的静态页面?
    • 我明白了:D 我删除了默认路由并为我的静态页面添加了新路由。其他所有东西都被蛞蝓路线拾取。顺便说一句,我还在蛞蝓 {*slug} 前面添加了一个星号 * 以便它接收所有内容。效果很好,谢谢大家!
    【解决方案2】:

    正如该站点上有关路由的问题数量所表明的那样,即使对于程序员来说,正确处理多个可能重叠的路由也很棘手。将这种范围广泛的功能交到最终用户手中是很可怕的。

    要回答您的问题,在应用程序启动时从数据库中读取“自定义”路由并照常映射它们是相当简单的。您通常不会在应用程序执行期间执行此操作,因为路由列表将在多个线程之间共享。如果您深入研究路由源代码,如果您确定必须在执行期间执行此操作,您可能会找到一种方法来保护路由表的“重建”。

    但是,我强烈建议您改用“站点”控制器的想法。考虑以下情况:路由既用于解析传入的 URI,也用于生成 URI。如果您的应用程序中甚至有一种情况是您使用ActionLink 而不是RouteLink,那么请考虑用户添加的路由可能会破坏您的整个站点。这意味着用户将无法修复他们的错误,即使他们意识到是他们造成的。

    【讨论】:

      【解决方案3】:

      我想到的最好的想法是使用“最后一种情况”的想法。

      基本上你有这种情况。

      1- 普通路由(例如:控制器/动作/id 路由)。
      2-您可以设置的任何特殊路线/区域(例如:管理员)
      3-写一个包罗万象的路线。此路由将在 db 中搜索由该路由命名的页面。如果该路由不存在,会抛出 404 page not found 错误。

      【讨论】:

        【解决方案4】:

        这就是最终代码的样子,感谢所有提供帮助的人!

        public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        
                routes.MapRoute(
                    "Home",
                    "",
                    new { controller = "Home", action = "Index" }
                );
        
                routes.MapRoute(
                    "Account",
                    "Account/{action}",
                    new { controller = "Account", Action = "Index" }
                );
        
                routes.MapRoute(
                    "Page",
                    "{*slug}",
                    new { controller = "Page", action = "ChoosePage" }
                );
        
            }
        

        【讨论】:

          【解决方案5】:

          这可以通过以下方式完成:

          1.在RouteTable中为该页面插入新路由

          RouteTable.Routes.Insert(1,new Route("Test", new RouteValueDictionary(new { controller = "Page", action = "ChoosePage" ,pagename="Test" }), new MvcRouteHandler()));
          
          public ActionResult ChoosePage(string pagename)
          {
              return View(pagename);
          }
          

          这将在运行时为新创建的页面解决路由,但这需要保存在数据库中。

          1. 编写代码从数据库中检索所有路由并写入 Global.asax.cs 文件 Application_Start()

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2023-03-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多