【问题标题】:MVCSiteMap: Should the nodes pickup current request parameter values?MVCSiteMap:节点是否应该获取当前请求参数值?
【发布时间】:2013-08-22 14:12:01
【问题描述】:

设置:

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

问题:

我有一个这样的节点:

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

SolarSystems 控制器上的Planets 动作有两个参数,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。

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

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

似乎发生了什么:

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

通过在节点中放入以下内容很容易解决问题:

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

这靠谱吗?!

注意(和问题重述):

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    根据issue that was submitted about this to the MVC team,此行为是设计使然。也就是说,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 一个节点才能成功完成此操作。

    请参阅issue @ GitHub 了解更多详情。

    【讨论】:

    • 这对我来说仍然是错误的。当然,它应该只将请求的参数应用于当前节点,并将路由注册默认值(如果未在节点中指定)用于其余节点,即使参数匹配?我看到的行为完全异常且出乎意料。但是,嘿嘿,如果是这样的话,我会把它标记为答案。
    • 我可能会在 github 上打开那个问题
    • 我根据你在 GitHub 上提供的信息更新了我的答案。
    • 我即将启程前往澳大利亚工作两周。我只会在回家后回复你。抱歉,感谢您的努力。
    • 我根据 GitHub 上另一个用户提供的信息更改了答案。
    猜你喜欢
    • 2018-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-28
    相关资源
    最近更新 更多