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

如何使用ASP.NET路由来路由树结构的URL?

  •  6
  • Venemo  · 技术社区  · 16 年前

    我想实现一些非常类似 this question

    有一个ASP.NET MVC web应用程序。


    例如,一个 Page IList<Page> 页码 类对应于数据库中的一行。)

    请注意,网站的所有者可以随时添加新页面,也可以删除现有页面,URL也应该反映这些更改。

    页码
    我来处理 页码 具有名为 PageController .

    http://mysite.com/Page1/
    http://mysite.com/Page1/SubPage/
    http://mysite.com/Page/ChildPage/GrandChildPage/
    

    你明白了。
    页码
    除此之外,我还希望能够映射单个 页码 /

    我想应用这些规则:

    1. 如果一个URL可以用任何其他路由来处理,或者文件系统中指定URL中存在一个文件,那么就让默认URL映射发生
    2. 如果没有其他URL,请将其他URL映射到 页面控制器

    我还发现 this question also this one this one ,但他们帮不了什么忙,因为他们没有解释我的前两点。

    我看到以下可能的原因:

    • 为每一页单独绘制一条路线。
      这要求我在应用程序启动时遍历整个树,并在route表的末尾添加一个完全匹配的路由。
    • {*path} 写一个习惯 IRouteHandler 这可以处理它,但是我不知道如何处理前两个规则,因为这个处理程序可以处理所有的事情。

    到目前为止,第一个解决方案似乎是正确的,因为它也是最简单的。但是,即使那样的话,我也不知道我怎么才能做到最好 页面控制器 处理请求。

    我真的很感激你的想法。

    提前谢谢!

    编辑:

    4 回复  |  直到 9 年前
        1
  •  3
  •   Neal    15 年前

    路由按其添加到集合的顺序进行处理。您可以在现有路由之后添加自定义路由,以确保它是最后一个有机会处理请求的路由。这将允许您在现有文件(虚拟文件或其他文件)之前添加路由,因此满足条件1和2。

    默认情况下,MVC路由将在应用路由集合中存储的任何路由之前路由到现有文件;看见 http://msdn.microsoft.com/en-us/library/system.web.routing.routecollection.routeexistingfiles.aspx

    要将请求路由到页面控制器,只需创建一个自定义路由来检查虚拟路径,如果它与数据库中某个页面的模式匹配,则返回 RouteData . 设置你的 路由数据 MvcRouteHandler (不确定这是否是正确的类名)。

    要确保正确返回到数据库驱动页的URL,请重写 GetVirtualPath( RequestContext, RouteValueDictionary ) RouteBase 并使用传入的路由值来确定这是否是数据库驱动的页,以及是否需要创建所需的虚拟路径数据(否则返回null)。

    获取有关重写的帮助 GetRouteData GetVirtualPath ,看反射的源代码 System.Web.Routing.RouteBase System.Web.Routing.Route ; 之后谷歌就是你的朋友。

    路由反过来用于确定给定控制器、操作和任何其他路由值的url。您应该能够利用它在请求的上下文中构建页面的url。

        2
  •  1
  •   user151323 user151323    16 年前

    一个不同的想法是使用T4(文本模板转换工具包)读取您的孩子一次,并生成Global.asax文件的内容。

    编辑:基本上与T4您可以自动生成文本文件。例如,不必手动复制某个巨大集合中的项,并将它们与特定上下文粘贴到文本文件中(如 INSERT INTO [MyTable] (Text) VALUES (@ItemText)

    我发现一个非常好的介绍可以从 Pro Entity Framework 4.0 书。

        3
  •  1
  •   Don    15 年前

    当你保存页面时,你知道你的页面结构。因此,您可以为每个页面生成URL并将其保存到数据库记录中。那你可以用 {*path} 规则并在数据库中找到精确匹配。此规则应该是规则定义中的最后一个规则,以便可以匹配其他路由。

    Page1 没有父页,其url为 第1页 SubPage 知道它是父级,所以它可以 Page1/SubPage 等。

        4
  •  1
  •   Andre Artus    15 年前

    "Page/{*path}" 图案。然后,您可以通过拆分/并遍历该字符串来分解路径,也可以使用Rarou建议将[generated]路径存储在DB中并进行直接查找。

    如果使用Rarou方法,则当父路径更改时,必须更新表中所有子路径的路径项。只需一个更新查询就可以做到这一点。

    我假设您正在将您希望用于主页的页面映射到配置文件或表条目中的某个位置。您可以让您的主页控制器执行查找并返回要呈现的主页视图的内容(您可以使用共享视图、部分视图或调用页面控制器,以便不复制行为),或者让它重定向到该页面。

    使用这种技术,您可以拥有一个页面控制器和视图,以相同的方式处理所有这些页面。您的其他需求似乎由MVC框架自动处理。

    您的路径如下所示:

    http://mysite.com/Page/Page1/ 
    http://mysite.com/Page/Page1/SubPage/ 
    http://mysite.com/Page/Page/ChildPage/GrandChildPage/