MVCSiteMap:节点是否应该获取当前请求参数值?

时间:2013-08-20 13:38:45

标签: asp.net-mvc-4 mvcsitemapprovider asp.net-mvc-sitemap

设定:

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

问题:

我有一个这样的节点:

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

Planets控制器上的SolarSystems操作有两个参数int order, int size,其中的顺序表示从星号开始的行星的顺序。例如,Mercury将为1,尺寸为行星的大小顺序,其中最小值为1

对于这两个参数,-1表示我没有线索。

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

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

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

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

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

例如,如果我的GalaxyClusters控制器的Index操作有两个参数int order and int size,并且在当前请求中,订单== 10009985639,大小= 9098,那么我的行星行动试图用这些值来寻找太阳系中的行星。

显然,它会失败,我们知道自伽利略时代以来。

似乎正在发生的事情:

换句话说,似乎MvcSitemap注入任何参数的当前值,如果找到匹配,则BOOM!这对我来说似乎不对,这是默认的吗?

通过在节点中添加以下内容可以轻松解决问题:

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

这可靠吗?!

注意(和问题重申):

我知道我已经回答了可能出现在我的问题中的问题,但如果你认为这样做,在投票结束这个问题之前,请仔细阅读:

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

最后,我真的没有一个应用程序可以记录宇宙中的所有星系(sql server可能不喜欢那么多记录,我会收到诺贝尔奖)。我刚刚调整了问题,因此我不使用客户端的域名。

1 个答案:

答案 0 :(得分:1)

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

根据issue that was submitted about this to the MVC team,此行为是设计使然。也就是说,URL生成代码将获取请求的环境值,并在它们匹配时自动将它们注入URL。

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

  1. 使用命名路由确保只使用您想要的路由来生成URL(这通常是一种很好的做法,尽管在这种特定情况下无效)
  2. 明确指定所有路径参数 - 甚至是您想要为空的值。这是解决这一特定问题的一种方法。
  3. 您可以使用Razor的〜/ syntax或调用Url.Content(“〜/ someurl”)来确保不会对您尝试的网址进行额外(或意外)处理,而不是使用路由来生成网址生成。
  4. 您可以使用MvcSiteMapProvider完成所有这三个解决方案。

    <!-- 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需要一个节点才能成功完成此任务。

    有关详细信息,请参阅issue @ GitHub