0

我在我的 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]-Attribute 它将再次起作用。所以我重新启动应用程序并且我不再工作 - >取消注释属性并且它再次工作,直到我重新启动它。

那怎么可能呢?

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

4

2 回答 2

4

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

  1. 在ItemDetails子节点的属性中指定settlementID父节点Item的路由参数。根据文档, inheritedRouteParameters 是不够的:preservedRouteParameters

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

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

希望这可以帮助...

于 2014-01-14T17:14:32.637 回答
1

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

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

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

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

更新

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

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

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

于 2013-08-11T18:04:51.310 回答