1

设置:

我在 ASP.NET MVC 4 应用程序中使用 MvcSiteMap 版本 3。

问题:

我有一个这样的节点:

<mvcSiteMapNode title="Neighbours" area="MilkyWay" controller="SolarSystems" action="Planets" key="neighbours">

控制器上的Planets动作SolarSystems有两个参数,int order, int size其中 order 表示行星从恒星开始的顺序。例如,Mercury将是1,并且大小是按大小排列的行星的顺序,其中最小的是1

对于这两个参数,-1意味着我不知道。

在我的路线注册中,我有类似的东西:

context.MapRoute(
                "SolarSystems_Planets",
                "SolarSystems/Planets/{order}/{size}",
                new { controller = "SolarSystems", action = "Index", order = -1, size = -1 }
            );

一切正常,即使用默认值...

...除非当前页面是具有相同名称的两个参数的操作。

在这种情况下,节点将使用这两个参数而不是默认值 -1。

例如,如果我有一个GalaxyClusters控制器,其Index动作有两个参数int order and int size,并且在当前请求中,order == 10009985639 和 size = 9098,那么我的行星动作试图在我们的太阳系中找到具有这些值的行星。

显然,它会失败,我们从伽利略时代就知道这一点。

似乎发生了什么:

换句话说,似乎 MvcSitemap 注入了任何参数的当前值,如果找到匹配项,那么 BOOM!这对我来说似乎是错误的,所以这是默认值吗?

通过在节点中放入以下内容可以轻松解决该问题:

<mvcSiteMapNode title="Neighbours" area="MilkyWay" controller="SolarSystems" action="Planets" order="" size="" key="neighbours">

这个靠谱吗?!

注意(和重申的问题):

我知道我已经回答了似乎是我的问题,但如果您认为,在投票结束问题之前,请仔细阅读:

我要问的问题是这是否是默认行为?如果是,为什么?并且:我的解决方案可靠吗?

最后,我真的没有一个应用程序可以对宇宙中的所有星系进行分类(sql server 可能不喜欢那么多记录,我会获得诺贝尔奖)。我只是调整了这个问题,这样我就不用我客户的域名了。

4

1 回答 1

1

此行为不是 MvcSiteMapProvider 的一部分,而是 MVC UrlHelper 类的一部分,他们不打算修复它。

根据提交给 MVC 团队的问题,这种行为是设计使然。也就是说,URL 生成代码将获取请求的环境值,并在它们匹配时自动将它们注入到 URL 中。

他们关于如何解决此问题的建议如下:

  1. 使用命名路由来确保只有你想要的路由会被用来生成 URL(这通常是一个很好的做法,尽管它在这个特定的场景中没有帮助)
  2. 明确指定所有路由参数 - 甚至是您希望为空的值。这是解决这个特定问题的一种方法。
  3. 您可以使用 Razor 的 ~/ 语法或调用 Url.Content("~/someurl") 来确保您尝试生成的 URL 不会发生额外(或意外)处理,而不是使用路由来生成 URL。

您可以使用 MvcSiteMapProvider 完成所有 3 个解决方案。

<!-- Using a named route -->
<mvcSiteMapNode title="Neighbours" area="MilkyWay" controller="SolarSystems" action="Planets" route="SolarSystems_Planets" key="neighbours">

这对您的情况无济于事,但我将其包括在此处以演示如何完成。

<!-- Specify parameters explicitly -->
<mvcSiteMapNode title="Neighbours" area="MilkyWay" controller="SolarSystems" action="Planets" order="10009985639" size="9098" key="neighbours">

这当然意味着您需要为每个订单和大小组合提供一个节点。如果数据来自某个共享资源(例如数据库),您可以实现IDynamicNodeProvider来为每个案例创建一个节点。当然,这假设您事先知道所有潜在价值是什么。

<!-- Specify the URL explicitly -->
<mvcSiteMapNode title="Neighbours" url="/MilkyWay/SolarSystems/Planets/10009985639/9098" key="neighbours">

同样,您需要每个 URL 一个节点才能成功完成此操作。

有关更多详细信息,请参阅有关此问题的@GitHub

于 2013-08-21T21:52:23.690 回答