Asp.Net 4.0 新特性之 使用自訂OutputCache Provider

來源:互聯網
上載者:User

在Asp.Net 4.0 的web.config檔案中添加了關於緩衝的配置節,如下所示:

  <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>

我們可以在Web.config中配置自訂的OutputCacheProvider,並將自訂Provider指定為預設的Provider。

1.自訂OutputCacheProvider需要實現System.Web.Cacheing. OutputCacheProvider抽象類別,網上有很多例子都用檔案快取做例子。這個例子太俗了,我寫了一個新的例子,在設定的緩衝時間小於指定閥值時,緩衝到HttpRuntime.Cache中,否則緩衝到檔案中,如下代碼:

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精靈,如果緩衝時間小於設定時間時則緩衝到記憶體,否則緩衝到檔案    /// </summary>    public class SmartOutputCacheProvider : OutputCacheProvider    {        private const string KEY_PREFIX = "__outputCache_";        /// <summary>        /// 初始化SmartOutputCacheProvider,讀取設定檔中配置的MemoryCacheLimit和FileCacheRoot的值        /// </summary>        /// <param name="name">provider名字</param>        /// <param name="config">配置</param>        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)        {            string memoryLimit = config["memoryCacheLimit"];            if (memoryLimit == null)            {                MemoryCacheLimit = 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>        /// 添加緩衝        /// </summary>        /// <param name="key">緩衝的鍵,key的值是有asp.net內部產生的</param>        /// <param name="entry">緩衝的對象</param>        /// <param name="utcExpiry">到期時間</param>        /// <returns>返回緩衝值</returns>        public override object Add(string key, object entry, DateTime utcExpiry)        {            Set(key, entry, utcExpiry);            return entry;        }        /// <summary>        /// 處理緩衝索引值,防止在檔案快取時出現檔案路徑不允許的字元        /// </summary>        /// <param name="key">緩衝鍵</param>        /// <returns>處理後的鍵</returns>        private string ProcessKey(string key)        {            return KEY_PREFIX + System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(key, "MD5");        }        /// <summary>        /// 返回快取檔案的實體路徑        /// </summary>        /// <param name="processedKey">處理後的鍵</param>        /// <returns>實體路徑</returns>        private string GetFilePath(string processedKey)        {            return Path.Combine(FileCacheRoot, processedKey + ".data");        }        /// <summary>        /// 獲得緩衝值,如果在HttpRuntime.Cache中有則直接讀取記憶體中的值,否則從檔案讀取        /// </summary>        /// <param name="key">緩衝鍵</param>        /// <returns>緩衝值</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>        /// 根據鍵移除緩衝        /// </summary>        /// <param name="key">緩衝鍵</param>        public override void Remove(string key)        {            string processedKey = ProcessKey(key);            HttpRuntime.Cache.Remove(processedKey);            string path = GetFilePath(processedKey);            if (!File.Exists(path))                File.Delete(path);        }        /// <summary>        /// 設定緩衝        /// </summary>        /// <param name="key">緩衝鍵</param>        /// <param name="entry">緩衝內容</param>        /// <param name="utcExpiry">到期時間</param>        public override void Set(string key, object entry, DateTime utcExpiry)        {            TimeSpan ts = utcExpiry - DateTime.UtcNow;            string processedKey = ProcessKey(key);            CacheDataWithExpiryTimeUtc cacheItem = new CacheDataWithExpiryTimeUtc            {                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>        /// 如果緩衝設定的時間超過此值則緩衝到檔案中,否則在HttpRuntime.Cache中做緩衝        /// </summary>        [XmlAttribute("memoryCacheLimit")]        public TimeSpan MemoryCacheLimit { get; set; }        /// <summary>        /// 檔案快取的根目錄,可以指定任何可訪問目錄        /// </summary>        [XmlAttribute("fileCacheRoot")]        public string FileCacheRoot { get; set; }    }    /// <summary>    /// 對快取資料和緩衝的到期時間的封裝    /// </summary>    [Serializable]    internal class CacheDataWithExpiryTimeUtc    {        public object Data { get; set; }        public DateTime ExpiryTimeUtc { get; set; }    }}

2.如何使用自訂的OutputCacheProvider

  1)在設定檔中做配置,將自訂的實現作為預設輸出緩衝支援,請看文章開始的配置
  2)在UserControl中指定使用Provider的名字,改名字在web.config中定義,例如

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="IamUserControl.ascx.cs" Inherits="OutputCacheTest.IamUserControl" %><%@ OutputCache Duration="3000" ProviderName="AspNetInternalProvider" VaryByParam="None" %>

  需要注意的是,只能在UserControl中指定Provider的名字,在Page的生明中是不允許的,在Page中預設情況會使用web.config中配置的defaultProvider,但是我們可以通過3)中介紹的方法給不同的頁面使用不同的OutputCacheProvider實現。

  3)在Global.asax檔案中重寫GetOutputCacheProviderName(HttpContext context)方法,根據context返回不同的實現名字,如下例子

public override string GetOutputCacheProviderName(HttpContext context){    if (context.Request.Path.StartsWith("/default.aspx",StringComparison.CurrentCultureIgnoreCase))    {        return "AspNetInternalProvider";    }                return base.GetOutputCacheProviderName(context);}

總結:
可擴充的OutputCache為我們提供了無限的可能,我們可以根據需要擴充OutputCache,例如把OutputCache儲存到Memcached server或者其他索引值對資料存放區中,從而使程式的效能達到最優的情況。

請注意:本文舉例中的代碼僅為範例程式碼,實際應用中需要考慮很多因素。

範例程式碼下載

Asp.net 新特性相關閱讀:

1. 從頁面標記<%%>說起
2. Asp.Net 4.0 中可以用自訂的Provider做OutputCache 了
3. SEO增強支援MetaKeywords,和MetaDescription,RedirectPermanant
4. SEO增強之URL Routing
5. 輸出更純淨的Html代碼,ViewStateMode和ClientIDMode,CheckBoxList等

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.