如何在运行时添加新的MvcSitemapProvider节点

时间:2013-02-05 13:08:28

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

我正在开发一个类似网络商店的asp.net mvc 4网站,其中包含一个wcf-service数据层。我的应用程序是使用maincategories,子类别和产品构建的。每个产品只能在一个子类别中,我的网址是这样的:

/ maincategoryname / subcategoryname / {的productid} / producttitle

相应的痕迹痕迹:

主页>主要类别>子类别> Producttitle

我目前正在使用MvcSitemapProvider生成导航菜单和面包屑。我正在将所有url加载为没有缓存的动态节点。这个解决方案适用于几种产品,但是当我添加1000个产品时,站点地图需要6.5秒才能填充,这太长了。

我在MvcSitemapProvider中打开了缓存。这样,应用程序加载速度更快。但是,当用户添加新产品并导航到此新产品(页面)时。 url尚未在sitemap文件中,因为它使用缓存。这样我的导航和面包屑就不会生成。

我的问题是:

在用户添加新产品后,是否可以在运行时向站点地图添加新节点?

2 个答案:

答案 0 :(得分:5)

接受的答案现在有点过时了。在MvcSiteMapProvider v4中,DynamicNodeProvider中不再存在GetCacheDescription()方法。这似乎无论如何都没有用。

您现在可以invalidate the cache manually使用更新数据的操作方法的[SiteMapCacheRelease]属性:

[MvcSiteMapProvider.Web.Mvc.Filters.SiteMapCacheRelease]
[HttpPost]
public ActionResult Edit(int id)
{

    // Update the record

    return View();
}

或者通过调用静态方法:

MvcSiteMapProvider.SiteMaps.ReleaseSiteMap();

您现在也可以选择将框架扩展到supply your own cache dependencies

答案 1 :(得分:0)

MvcSiteMapProvider允许Dynamic Sitemaps解决Cache Dependancies。

您可以通过创建实现IDynamicNodeProvider的类来启用此功能。 下面是一个基于数据库查询生成动态节点的示例,还可以在同一查询上设置缓存依赖项。

public class ProductNodesProvider : IDynamicNodeProvider
{
  static readonly string AllProductsQuery = 
    "SELECT Id, Title, Category FROM dbo.Product;";
  string connectionString = 
        ConfigurationManager.ConnectionStrings ["db"].ConnectionString;

  /// Create DynamicNode's out of all Products in our database
  public System.Collections.Generic.IEnumerable<DynamicNode> GetDynamicNodeCollection()
  {
    var returnValue = new List<DynamicNode> ();

    using (SqlConnection connection = new SqlConnection(connectionString)) {
      SqlCommand command = new SqlCommand (AllProductsQuery, connection);
      connection.Open ();
      SqlDataReader reader = command.ExecuteReader ();
      try {
        while (reader.Read()) {
          DynamicNode node = new DynamicNode (); 
          node.Title = reader [1]; 
          node.ParentKey = "Category_" + reader [2]; 
          node.RouteValues.Add ("productid", reader [0]);

          returnValue.Add (node); 
        }
      } finally {
        reader.Close ();
      }
    }

    return returnValue;
  }

  /// Create CacheDependancy on SQL
  public CacheDescription GetCacheDescription ()
  {
    using (SqlConnection connection = new SqlConnection(connectionString)) {
      SqlCommand command = new SqlCommand (AllProductsQuery, connection);
      SqlCacheDependency dependancy = new SqlCacheDependency (command);

      return new CacheDescription ("ProductNodesProvider")
      {
        Dependencies = dependancy
      };
    }
  }
}

虽然这非常有趣 - 并且当客户更改数据库中的产品时应该使缓存无效 - 整个SqlCacheDependancy可能很棘手并且依赖于SQL Server版本。

如果您使用缓存来存储产品,则可以使用自定义CacheDependacy