【问题标题】:MvcSitemapProvider parameters sometimes works sometimes notMvcSitemapProvider 参数有时有效,有时无效
【发布时间】:2013-08-11 16:33:52
【问题描述】:

我在我的 MVC4 应用程序中使用 MvcSitemapProvider。我的控制器操作需要参数来解析数据库中的 1:n 关系。例如:商店 > 商品 > 商品详情。假设用户查看 ItemXYZ 的详细信息并单击 Shop > Item > ItemDetails 我希望应用程序再次显示 ItemXYZ。所以 MvcSitemapProvider 必须存储 itemID。奇怪的行为是,当我更改任何代码时,运行它-> 它可以工作。如果我停止它,重新启动它(使用完全相同的代码)它不起作用。如果我再次更改任何代码-> 它再次工作。那怎么可能。这是我的站点地图配置:

<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0"
            xsi:schemaLocation="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-4.0 MvcSiteMapSchema.xsd">

  <mvcSiteMapNode title="Werk" controller="Settlement" action="Index">
    <mvcSiteMapNode title="Abteilung" controller="Section" action="Index" preservedRouteParameters="settlementID" inheritedRouteParameters="settlementID">
      <mvcSiteMapNode title="Maschine" controller="Machine" action="Index" preservedRouteParameters="sectionID" inheritedRouteParameters="sectionID"/>
    </mvcSiteMapNode>
  </mvcSiteMapNode>

</mvcSiteMap>

这是一个控制器(看起来都一样):

public class SectionController : ControllerBase
{
    //
    // GET: /Section/

    [SiteMapPreserveRouteData]
    public ActionResult Index(int settlementID)
    {
        using (var e = new ClapEntities())
        {
            return View(e.Sections.Where(x => x.SettlementID == settlementID).ToList());
        }
    }
}

除非我不重新启动应用程序,否则这是一个工作代码。如果我重新启动应用程序,它不起作用。但是,如果我发表评论,例如[SiteMapPreserveRouteData]-属性将再次起作用。所以我重新启动应用程序,我不再工作 -> 取消注释属性,它再次工作,直到我重新启动它。

那怎么可能呢?

编辑: 它与更改代码没有任何关系。当我在 Visual Studio 菜单中选择重建时,它可以工作。如果没有,它不会工作两次。

【问题讨论】:

  • 仅供参考 - 我已经(第二次)向 Maarten 提出关于从项目中删除 SiteMapPreserveRouteDataAttribute 的案例。仔细分析后,我看不出它怎么可能做任何有用的事情。我建议不要使用它。

标签: c# asp.net-mvc asp.net-mvc-4 mvcsitemapprovider


【解决方案1】:

我遇到了这样的事情。我必须做两件事:

  1. ItemDetails子节点的preservedRouteParameters属性中指定父节点ItemsettlementID路由参数。根据docsinheritedRouteParameters 是不够的:

    <mvcSiteMapNode title="Maschine" controller="Machine" action="Index" preservedRouteParameters="settlementID,sectionID"/>
    
  2. 确保所有preservedRouteParameters 都存在于action 方法中。我不确定您的 ItemsDetails 操作方法是什么样的,但它需要看起来像这样:

    public ActionResult Index(int settlementID, int sectionID)
    {
        //....
    }
    

希望这会有所帮助...

【讨论】:

    【解决方案2】:

    我不确定您在遵循什么示例,但此配置存在一些问题:

    1. inheritedRouteParameters 用于从父节点(mvcSiteMapNode)继承参数。您的示例表明,settlementID 是 SectionController 的一部分,而不是 SettlementController,因此无需继承它。
    2. 您同时使用了preservedRouteParameters 和SiteMapPreserveRouteDataAttribute。这些不能同时使用。

    另外,请确保您拥有最新版本(当前为 4.0.6),因为自正式发布以来已经修复了一些节点匹配的错误。

    如果您修复了这些问题但仍然有问题,请创建一个重现该行为的小型演示项目,然后将其发布到 GitHub 上或将其压缩以供下载,然后open a new issue 并发布您的演示位置所以我们可以看看。

    更新

    我重读了您的问题并注意到您正在尝试显示数据库中的产品。当您有基于数据库数据列表或表的导航时,使用preservedRouteParameters 仅对SiteMapPath (breadcrumb) HTML 帮助程序有用。它用于通过从当前 HTTP 请求中复制参数的值来强制每个 id 匹配单个节点。

    但是,除非每个产品的站点地图中都添加了实际节点,否则您将无法在其他 HTML 帮助程序(例如 Menu 或 SiteMap)中查看它们,更重要的是,它们不会出现在 /sitemaps.xml搜索引擎的端点。

    我猜您希望您的产品在搜索引擎中被索引,因此我建议您改用dynamic node providers 将您的节点从您的数据库加载到站点地图中。这会将它们全部存储在共享缓存中,因此非常有效,并且它们不会在请求之间被“遗忘”。只需确保使用node.RouteValues.Add("id", product.id) 设置每个产品的 id,以便有一个唯一的 ID 进行匹配。

    【讨论】:

    • 好吧,我解决了这个问题,但仍然存在完全相同的行为。如果我选择重建它一次。 @NightOwl888
    • 哦,我正在使用 nuget... 应该是最新版本
    • 对不起,我之前没有注意到你的 cmets。我已经更新了我的答案。
    猜你喜欢
    • 2015-02-11
    • 2012-08-02
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多