DiskCacheProvider в ASP.Net 4.0 действительно существует? - PullRequest
0 голосов
/ 29 ноября 2011

Я читал во многих местах, сказал, что новая функция в ASP.net 4.0, и код:

    <caching>
        <outputCache defaultProvider="AspNetInternalProvider">
            <providers>
                <add name="DiskCache"
                    type="test.OutputCacheEx.DiskOutputCacheProvider, DiskCacheProvider"/>
            </providers>
        </outputCache>
    </caching>

В любом случае, я не могу заставить его работать, я изменяю код наизнанку, бесполезно. Я не могу найти только одного провайдера кеша от Microsoft, который с asp.net поставляет AspNetInternalProvider

Итак, действительно ли DiskOutputCacheProvider существует? Если да, то как его использовать.

Кроме того, мне нужно использовать его в Azure, так что я думаю, здесь должно быть место для дискового кэша для установки папки кэша, верно?

Если у кого-нибудь есть решение для кэширования диска для лазури (используйте LocalResources.LocalStorage или нет), пожалуйста, поделитесь со мной, бесплатно или за плату. Благодаря.

Ответы [ 2 ]

1 голос
/ 15 сентября 2012
// Based on code by 'Scott Mitchell' <mitchell@4guysfromrolla.com>
// http://www.4guysfromrolla.com/articles/061610-1.aspx

// Add the following to Web.config
// Use the cacheFolder attribute to specify the disk location for the cache
//
// <system.web>
//    <caching>
//       <outputCache enableOutputCache="true" defaultProvider="disk">
//          <providers>
//             <add name="disk" type="DiskOutputCache.DiskOutputCacheProvider, DiskOutputCache" cacheFolder="~/App_Data/OutputCache" />
//          </providers>
//       </outputCache>
//    </caching>
// </system.web> 

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Web;
using System.Web.Caching;

namespace DiskOutputCache {

   /// <summary>
   /// An <see cref="OutputCacheProvider"/> that uses the file system for storage.
   /// </summary>
   public class DiskOutputCacheProvider : OutputCacheProvider {

      readonly IDictionary<string, CacheItem> cacheItems = new ConcurrentDictionary<string, CacheItem>();
      string cacheFolder;

      public override void Initialize(string name, NameValueCollection config) {

         HttpServerUtility serverUtil = HttpContext.Current.Server;

         const string cacheFolderKey = "cacheFolder";
         string cacheFolderValue = config[cacheFolderKey];
         string folder;

         if (!String.IsNullOrEmpty(cacheFolderValue)) {

            folder = serverUtil.MapPath(cacheFolderValue);

            config.Remove(cacheFolderKey);

         } else {
            throw new ArgumentException(String.Format("The attribute '{0}' is missing in the configuration of the '{1}' provider.", cacheFolderKey, name));
         }

         if (folder[folder.Length - 1] != Path.DirectorySeparatorChar)
            folder += Path.DirectorySeparatorChar;

         if (!Directory.Exists(folder))
            Directory.CreateDirectory(folder);

         this.cacheFolder = folder;

         base.Initialize(name, config);
      }

      public override object Add(string key, object entry, DateTime utcExpiry) {

         // See if this key already exists in the cache. If so, we need to return it and NOT overwrite it!
         object results = Get(key);

         if (results != null)
            return results;

         // If the item is NOT in the cache, then save it!
         Set(key, entry, utcExpiry);

         return entry;
      }

      public override object Get(string key) {

         CacheItem item;

         if (!this.cacheItems.TryGetValue(key, out item))
            return null;

         if (item.UtcExpiry < DateTime.UtcNow) {

            // Item has expired
            Remove(key, item);

            return null;
         }

         return GetCacheData(item);
      }

      object GetCacheData(CacheItem item) {

         string fileToRetrieve = GetFilePath(item);

         BinaryFormatter formatter = new BinaryFormatter();
         Stream source = null;

         try {
            source = new FileStream(fileToRetrieve, FileMode.Open, FileAccess.Read, FileShare.Read);

            return formatter.Deserialize(source);

         } catch (IOException) {

         } finally {
            if (source != null)
               source.Dispose();
         }

         return null;
      }

      public override void Remove(string key) {

         CacheItem item;

         if (this.cacheItems.TryGetValue(key, out item)) 
            Remove(key, item);
      }

      void Remove(string key, CacheItem item) {

         RemoveCacheData(item);
         this.cacheItems.Remove(key);
      }

      void RemoveCacheData(CacheItem item) {

         string fileToDelete = GetFilePath(item);

         try {
            File.Delete(fileToDelete);
         } catch (IOException) { }
      }

      public override void Set(string key, object entry, DateTime utcExpiry) {

         // Create a DiskOutputCacheItem object
         CacheItem item = new CacheItem(key, utcExpiry);

         WriteCacheData(item, entry);

         // Add item to CacheItems, if needed, or update the existing key, if it already exists
         this.cacheItems[key] = item;
      }

      void WriteCacheData(CacheItem item, object entry) {

         string fileToWrite = GetFilePath(item);

         BinaryFormatter formatter = new BinaryFormatter();
         Stream destination = null;

         try {
            destination = new FileStream(fileToWrite, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
            formatter.Serialize(destination, entry);

         } catch (IOException) {

         } finally {
            if (destination != null)
               destination.Dispose();
         }
      }

      string GetFilePath(CacheItem item) {
         return this.cacheFolder + item.FileName;
      }

      class CacheItem {

         static readonly char[] invalidFileNameChars = Path.GetInvalidFileNameChars();

         public string FileName { get; private set; }
         public DateTime UtcExpiry { get; private set; }

         public CacheItem(string key, DateTime utcExpiry) {

            this.FileName = GetSafeFileName(key);
            this.UtcExpiry = utcExpiry;
         }

         string GetSafeFileName(string unsafeFileName) {

            char[] invalid = unsafeFileName.ToCharArray()
               .Where(c => invalidFileNameChars.Contains(c))
               .ToArray();

            if (invalid.Length > 0) {

               var sb = new StringBuilder(unsafeFileName, unsafeFileName.Length);

               for (int i = 0; i < invalid.Length; i++) 
                  sb.Replace(invalid[i], '_');

               return sb.ToString(); 
            }

            return unsafeFileName;
         }
      }
   }
}
1 голос
/ 29 ноября 2011

DiskCacheOutputProvider не входит в .net 4.0 нет.Но вы можете расширить .net 4.0 кеширование и создать свой собственный.В Интернете есть несколько примеров того, как это делается.

http://weblogs.asp.net/scottgu/archive/2010/01/27/extensible-output-caching-with-asp-net-4-vs-2010-and-net-4-0-series.aspx

Необходимую реализацию можно найти здесь

** http://aspnet.4guysfromrolla.com/code/ExtensibleOutputCachingDemo.zip** Источник от http://www.4guysfromrolla.com/articles/061610-1.aspx

Это всего лишь пример кода и не готов к прайм-тайм, поэтому остерегайтесь его использовать.Вы должны подключить все это в web.config.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...