2011-11-29 19 views
0

我看了很多地方說,在ASP.net 4.0的新功能,而且代碼:ASP.Net 4.0中的DiskCacheProvider真的存在嗎?

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

反正我不能得到它的工作,我更改代碼裏面出來,沒有用。我不僅可以找到微軟提供的1個緩存提供程序,這些提供商使用asp.net提供的是AspNetInternalProvider

所以,DiskOutputCacheProvider是否真的存在?如果是,如何使用它。

另外,我需要在Azure中使用它,所以我猜這裏是必須有一個磁盤緩存來設置緩存文件夾的地方,對吧?

如果有人有Azure的磁盤緩存解決方案(使用LocalResources.LocalStorage或不),請與我分享,免費或付費。謝謝。

+0

你可以發佈你的DiskOutputCacheProvider類嗎? –

回答

1

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。

+0

在這裏是什麼黃金時段的產品? –

+0

不是我所知道的。我確信所提供的解決方案可以通過測試轉化爲解決方案,但是您將會面臨無法執行的風險,或者您有時會丟失數據。我確信有人編寫了一個memcached提供程序,它可能會做更多你想實現的功能。 –

+0

我查了一下這個示例,我想最明顯的問題是當磁盤滿了,代碼會崩潰。無論如何,我想asp.net 4.0仍然是相當新的,並可能在開發中的一些產品:) –

1
// Based on code by 'Scott Mitchell' <[email protected]> 
// 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; 
     } 
     } 
    } 
}