Add the cache configuration section in the web. config file of Asp. Net 4.0, as shown below:
<system.web> <compilation debug="true" targetFramework="4.0" /> <caching> <outputCache defaultProvider="SmartOutputCache"> <providers> <add name="SmartOutputCache" type="OutputCacheTest.Caching.SmartOutputCacheProvider" memoryCacheLimit="00:30:00" /> </providers> </outputCache> </caching> </system.web>
You can configure the custom OutputCacheProvider in Web. config and specify the custom Provider as the default Provider.
1. Custom OutputCacheProvider must implement the System. Web. Cacheing. OutputCacheProvider abstract class. Many examples on the Internet Use File Cache as an example. This example is too vulgar. I wrote a new example. When the set cache time is smaller than the specified threshold value, it is cached to HttpRuntime. cache; otherwise, Cache the file with the following code:
Using System; using System. collections. generic; using System. linq; using System. web; using System. web. caching; using System. xml. serialization; using System. IO; using System. runtime. serialization. formatters. binary; namespace OutputCacheTest. caching {/// <summary> /// OutputCache genie. If the cache time is earlier than the set time, It is cached to the memory, otherwise, cache it to the file // </summary> public class SmartOutputCacheProvider: OutputCacheProvider {private const string KE Y_PREFIX = "_ outputCache _"; // <summary> // initialize SmartOutputCacheProvider, read the values of MemoryCacheLimit and FileCacheRoot configured in the configuration file /// </summary> /// <param name = "name"> provider name </param> /// <param name = "config"> Configuration </param> public override void Initialize (string name, system. collections. specialized. nameValueCollection config) {string memoryLimit = config ["memoryCacheLimit"]; if (memoryLimit = null) {MemoryC AcheLimit = new TimeSpan (0, 30, 0);} else {MemoryCacheLimit = TimeSpan. parse (memoryLimit);} string fileCacheRoot = config ["fileCachRoot"]; if (string. isNullOrEmpty (fileCacheRoot) {fileCacheRoot = AppDomain. currentDomain. baseDirectory + "cache \";} this. fileCacheRoot = fileCacheRoot; base. initialize (name, config );} /// <summary> /// add cache /// </summary> /// <param name = "key"> cache key. The key value is asp. n </Param> /// <param name = "entry"> cached object </param> /// <param name = "utcExpiry"> expiration time </param> // <returns> return the cache value </returns> public override object Add (string key, object entry, DateTime utcExpiry) {Set (key, entry, utcExpiry); return entry ;}/// <summary> // process the cache key value, prevent files from being cached with characters that are not allowed by the file path /// </summary> /// <param name = "key"> cache key </param> /// <returns> processed key </returns> private string ProcessKey (string Key) {return KEY_PREFIX + System. web. security. formsAuthentication. hashPasswordForStoringInConfigFile (key, "MD5 ");} /// <summary> /// return the physical path of the cached file /// </summary> /// <param name = "processedKey"> processed key </param >/// <returns> physical path </returns> private string GetFilePath (string processedKey) {return Path. combine (FileCacheRoot, processedKey + ". data ") ;}/// <summary> // obtain the cache value. the Cache directly reads the memory. Value in, otherwise, read the file /// </summary> /// <param name = "key"> cache key </param> /// <returns> cache value </returns> public override object Get (string key) {string processedKey = ProcessKey (key); CacheDataWithExpiryTimeUtc result = HttpRuntime. cache [processedKey] as CacheDataWithExpiryTimeUtc; if (result = null) {string path = GetFilePath (processedKey); if (! File. exists (path) return null; using (FileStream file = File. openRead (path) {var formatter = new BinaryFormatter (); result = (CacheDataWithExpiryTimeUtc) formatter. deserialize (file) ;}} if (result = null | result. expiryTimeUtc <= DateTime. utcNow) {Remove (key); return null;} return result. data ;} /// <summary> /// remove the cache based on the key /// </summary> /// <param name = "key"> cache key </param> public override void R Emove (string key) {string processedKey = ProcessKey (key); HttpRuntime. Cache. Remove (processedKey); string path = GetFilePath (processedKey); if (! File. exists (path) File. delete (path );} /// <summary> /// set the cache /// </summary> /// <param name = "key"> cache key </param> /// <param name = "entry"> cached content </param> // <param name = "utcExpiry"> expiration time </param> public override void Set (string key, object entry, DateTime utcExpiry) {TimeSpan ts = utcExpiry-DateTime. utcNow; string processedKey = ProcessKey (key); CacheDataWithExpiryTimeUtc cacheItem = new expiration {Data = entry, ExpiryTimeUtc = utcExpiry}; if (ts <= MemoryCacheLimit) {HttpRuntime. cache. insert (processedKey, cacheItem, null, utcExpiry. toLocalTime (), TimeSpan. zero);} else {string cacheFilePath = GetFilePath (processedKey); using (var fs = new FileStream (cacheFilePath, FileMode. openOrCreate, FileAccess. readWrite) {var formatter = new BinaryFormatter (); formatter. serialize (fs, cacheItem) ;}}/// <summary> // If the cache time exceeds this value, it is cached in the file; otherwise, it is in HttpRuntime. cache // </summary> [XmlAttribute ("memoryCacheLimit")] public TimeSpan MemoryCacheLimit {get; set ;} /// <summary> /// root directory of the File Cache. You can specify any accessible directory. /// </summary> [XmlAttribute ("fileCacheRoot")] public string FileCacheRoot {get; set ;}} /// <summary> /// encapsulation of cached Data and cache expiration time /// </summary> [Serializable] internal class CacheDataWithExpiryTimeUtc {public object Data {get; set;} public DateTime ExpiryTimeUtc {get; set ;}}}
2. How to Use the custom OutputCacheProvider
1) Configure in the configuration file and use the custom implementation as the default output cache support. Please refer to the configuration at the beginning of this article.
2) Specify the Provider name in UserControl and change the name to be defined in web. config. For example:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="IamUserControl.ascx.cs" Inherits="OutputCacheTest.IamUserControl" %><%@ OutputCache Duration="3000" ProviderName="AspNetInternalProvider" VaryByParam="None" %>
You must note that you can only specify the Provider name in UserControl. It is not allowed in the description of the Page. By default, web is used in the Page. the defaultProvider configured in config, but we can use the methods described in 3) to use different OutputCacheProvider for different pages.
3) in the Global. asax file, rewrite the GetOutputCacheProviderName (HttpContext context) method and return different implementation names based on the context. The following example
public override string GetOutputCacheProviderName(HttpContext context){ if (context.Request.Path.StartsWith("/default.aspx",StringComparison.CurrentCultureIgnoreCase)) { return "AspNetInternalProvider"; } return base.GetOutputCacheProviderName(context);}
Summary:
Scalable OutputCache provides unlimited possibilities for us. We can expand OutputCache as needed, such as storing OutputCache in Memcached server or other key-value pair data storage, in this way, the program performance can be optimized.
Note: The code in this example is only the sample code. Many factors need to be taken into account in actual application.
Download Sample Code
Reading about new features of Asp.net:
1. Start with the page tag <%>
2. in Asp. Net 4.0, you can use a custom Provider for OutputCache.
3. Enhanced SEO support for MetaKeywords, metadegion, and RedirectPermanant
4. SEO-enhanced URL Routing
5. Output more pure Html code, ViewStateMode, ClientIDMode, CheckBoxList, etc.