我想取得与非常相似的东西 这个问题, ,有一些增强。

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

我有一棵实体树。
例如, Page 班级有一个叫儿童的财产,类型 IList<Page>. 。 (一个实例 Page 类对应于数据库中的一行。)

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

我想为每个分配一个唯一的URL Page 在数据库中。
我处理 Page 带有控制器的对象称为 PageController.

示例URL:

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

你得到图片。
所以,我想要每一 Page 对象具有自己的URL等于其父级的URL加上自己的名字。
除此之外,我还希望能够映射一个 Page/ (根)URL。

我想应用以下规则:

  1. 如果可以使用任何其他路由来处理URL,或者在指定URL中的文件系统中存在文件,则默认URL映射发生
  2. 如果虚拟路径提供商可以处理URL,请让它处理
  3. 如果没有其他,则将其他URL映射到 PageController 班级

我也发现 这个问题, , 和 也是这个这个, ,但是它们没有太大帮助,因为它们没有提供有关我的前两个分的解释。

我看到以下可能的Soutions:

  • 为每个页面绘制一条路由。
    这要求我在应用程序启动时越过整棵树,并在路由表的末端添加精确的匹配路由。
  • 我可以添加一条路线 {*path} 并写一个自定义 IRouteHandler 这可以处理它,但是我看不到我该如何处理前两个规则,因为这个处理程序可以处理所有内容。

到目前为止,第一个解决方案似乎是正确的解决方案,因为它也是最简单的解决方案。但是,即使在那种情况下,我不确定如何使 PageController 处理请求。

我真的很感谢您对此的想法。

先感谢您!

编辑:我现在有时间检查收到的每个答案的各个方面。我接受了尼尔的回答,因为他是关于事情如何工作的最佳解释的人。我还提供了所有其他答案,因为它们提供了好主意。

有帮助吗?

解决方案

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

默认情况下,在应用路由集合中存储的任何路由之前,MVC路由将路由到现有文件;看 http://msdn.microsoft.com/en-us/library/system.web.routing.routecollection.routeexistingfiles.aspx. 。 (对保罗的哈蒂普 - 请参阅评论)。

要将请求路由到您的页面控制器,只需创建一个自定义路由,该路由检查虚拟路径,如果它与数据库中的页面的模式匹配,则返回 RouteData. 。设置您的 RouteData 通过从虚拟路径提取的适当值(例如将路径键设置为/父/子/孙子),将控制器键设置为页面控制器名称(例如页面),将操作设置为要执行的操作名称(例如显示)。这 RouteData 应该用 MvcRouteHandler (不确定这是否是正确的类名称)。

为确保正确返回数据库驱动页面的URL,请覆盖 GetVirtualPath( RequestContext, RouteValueDictionary ) 的方法 RouteBase 并使用传递的路由值来确定这是否是数据库驱动的页面以及是否创建所需的虚拟路径数据(或否则返回null)。

寻求覆盖 GetRouteDataGetVirtualPath, ,查看反映的源代码 System.Web.Routing.RouteBaseSystem.Web.Routing.Route;之后,Google是您的朋友。

反向使用路由以确定给定控制器,操作和任何其他路线值的URL。您应该能够利用它来在要求的上下文中构建页面的URL。

其他提示

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

编辑:通过T4的基础,您可以自动化文本文件生成。例如,而不是手动将某些巨大集合的项目复制并用某些特定上下文粘贴到文本文件中(例如 INSERT INTO [MyTable] (Text) VALUES (@ItemText))您可以让T4引擎读取该集合并为您生成这些插入语句。它是静态的,不适合运行时。

我发现可以从 Pro实体框架4.0 书。

但是,如果您说需要动态地进行操作,那么这可能不是您的工具。

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

例如,您的 Page1 没有父母页面,它是URL Page1. 。您的 SubPage 知道它是父母,所以它可以使用URL Page1/SubPage 等等

您可以使用 "Page/{*path}" 图案。然后,您可以通过将字符串在'/'上划分并走到它来分解路径,也可以使用rarouš”建议将[生成]路径存储在DB中并直接查找。

如果您使用rarouš的方法,那么当父路径更改时,您将必须为所有孩子的表中的路径条目更新。通过单个更新查询可以简单地完成此操作。

我假设您要映射要在配置文件或表条目中某个地方的主页上使用的页面。您可以让主页控制器执行查找并返回内容以呈现“主页”视图(您可以使用共享视图,部分视图或拨打页面控制器,以使您不重复行为)或您可以将其重定向到该页面。

使用此技术,您可以拥有一个单页控制器,并以相同的方式查看处理所有这些页面。 MVC框架似乎会自动处理您的其他要求。

您的道路看起来像这样:

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

您当然可以使用“页面”以外的其他前缀。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top