【问题标题】:How to add a new MvcSitemapProvider node at runtime如何在运行时添加新的 MvcSitemapProvider 节点
【发布时间】:2013-02-05 13:08:27
【问题描述】:

我正在开发一个类似 webshop 的带有 wcf-service 数据层的 asp.net mvc 4 网站。我的应用程序是使用主类别、子类别和产品构建的。每个产品只能在一个子类别中,我的网址是这样的:

/maincategoryname/subcategoryname/{productid}/producttitle

以及对应的面包屑路径:

首页 > 主分类 > 子分类 > 产品标题

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

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

我的问题是:

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

【问题讨论】:

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


    【解决方案1】:

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

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

    [MvcSiteMapProvider.Web.Mvc.Filters.SiteMapCacheRelease]
    [HttpPost]
    public ActionResult Edit(int id)
    {
    
        // Update the record
    
        return View();
    }
    

    或者通过调用静态方法:

    MvcSiteMapProvider.SiteMaps.ReleaseSiteMap();
    

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

    【讨论】:

      【解决方案2】:

      MvcSiteMapProvider 允许 Dynamic Sitemaps 解决缓存依赖关系。

      您可以通过创建一个实现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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多