问题
I read many places said the new feature in ASP.net 4.0, and the code is:
<caching>
<outputCache defaultProvider="AspNetInternalProvider">
<providers>
<add name="DiskCache"
type="test.OutputCacheEx.DiskOutputCacheProvider, DiskCacheProvider"/>
</providers>
</outputCache>
</caching>
Anyway, I cannot get it work, I change the code inside out, no use. I cannot only find 1 cache provider from Microsoft which shipping with asp.net is AspNetInternalProvider
So, Is DiskOutputCacheProvider really exist? If yes, how to use it.
Also, I need to use it in Azure, so I guess is here must have a place for disk cache to setup cache folder, right?
If anyone has a disk cache solution for azure (use LocalResources.LocalStorage or not), please share with me, free or paid. Thanks.
回答1:
The DiskCacheOutputProvider is not include in .net 4.0 no. But you can extend .net 4.0 caching and create your own. There are some examples online of how this is done.
http://weblogs.asp.net/scottgu/archive/2010/01/27/extensible-output-caching-with-asp-net-4-vs-2010-and-net-4-0-series.aspx
The implementation you are looking for can be found here
** http://aspnet.4guysfromrolla.com/code/ExtensibleOutputCachingDemo.zip ** Sourced from http://www.4guysfromrolla.com/articles/061610-1.aspx
It is just sample code and not ready for prime time so beware of using this. You have to wire it all up in the web.config.
回答2:
// 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;
}
}
}
}
来源:https://stackoverflow.com/questions/8312352/is-diskcacheprovider-in-asp-net-4-0-really-exist