ASP.NET 4针对输出缓存增加了一个扩展点,它能够使你可以配置一个或多个自定义输出缓存提供程序。输出缓存提供程序可以使用任何的存储机制来存储HTML内容。这使得开发者有可能针对不同的持久性机制来创建自定义的输出缓存提供程序,其中可以包括本地或远程磁盘、数据库、云存储和分布式缓存引擎(如velocity、memcached)等等。
要实现自定义输出缓存提供程序,你可以通过从System.Web.Caching.OutputCacheProvider类中派生一个类来创建自定义输出缓存提供程序。例如,下面的MyOutputCacheProvider类就是派生自OutputCacheProvider类,并创建了一个自定义输出缓存提供程序,如代码清单19-5所示:
代码清单19-5:MyOutputCacheProvider.cs
代码如下 | 复制代码 |
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Timers; using System.Web.Caching; using System.Collections.Concurrent; namespace _19_1 { public class MyOutputCacheProvider : OutputCacheProvider { private Timer timer; private string cachePath = "C:Cache"; private ConcurrentDictionary cacheExpireList; private const string KEY_PREFIX = "__outputCache_"; public MyOutputCacheProvider() { cacheExpireList = new ConcurrentDictionary timer = new Timer(3000); timer.Elapsed += (o, e) => { var discardedList = from cacheItem in cacheExpireList where cacheItem.Value < DateTime.Now select cacheItem; foreach (var discarded in discardedList) { Remove(discarded.Key); DateTime discardedDate; cacheExpireList.TryRemove(discarded.Key, out discardedDate); } }; timer.Start(); } /// /// 添加缓存 /// /// 缓存的键 /// 缓存的对象 /// 过期时间 /// public override object Add(string key, object entry, DateTime utcExpiry) { FileStream fs = new FileStream( String.Format("{0}{1}.binary", cachePath, key), FileMode.Create, FileAccess.Write); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fs, entry); fs.Close(); cacheExpireList.TryAdd(key, utcExpiry.ToLocalTime()); return entry; } /// /// 获得缓存值 /// /// 缓存键 /// public override object Get(string key) { string path = String.Format("{0}{1}.binary", cachePath, key); if (File.Exists(path)) { FileStream fs = new FileStream( path, FileMode.Open, FileAccess.Read); BinaryFormatter formatter = new BinaryFormatter(); object result = formatter.Deserialize(fs); fs.Close(); return result; } else { return null; } } /// /// 根据键移除缓存 /// /// 缓存键 public override void Remove(string key) { string path = String.Format("{0}{1}.binary", cachePath, key); if (File.Exists(path)) { File.Delete(path); } } /// /// 设置缓存 /// /// 缓存的键 /// 缓存的对象 /// 过期时间 public override void Set(string key, object entry, DateTime utcExpiry) { string path = String.Format("{0}{1}.binary", cachePath, key); FileStream fs = new FileStream( path, FileMode.Create, FileAccess.Write); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fs, entry); fs.Close(); cacheExpireList.TryAdd(key, utcExpiry.ToLocalTime()); } } } |
在MyOutputCacheProvider类中,我们重写了OutputCacheProvider类的Add、Get、Remove与Set方法,并将页输出缓存到“C:Cache”文件夹里。
定义好MyOutputCacheProvider类之后,你可以通过使用OutputCache元素的新的providers节在Web.config文件中配置提供程序,如下面的示例所示:
代码如下 | 复制代码 |
type="_19_1.MyOutputCacheProvider,19-1"/> |
默认情况下,在ASP.NET 4中所有的HTTP响应、生成的网页以及控件都使用内存输出缓存,其中defaultProvider属性被默认设置为AspNetInternalProvider。当然,你可以更改Web应用程序中所使用的默认的输出缓存提供程序,这是通过为defaultProvider指定一个不同的提供程序名称实现的。如下面的代码所示:
代码如下 | 复制代码 |
type="_19_1.MyOutputCacheProvider,19-1"/> |
此外,还可以针对每个控件和每个请求选择不同的输出缓存提供程序。为不同的Web用户控件选择不同的输出缓存提供程序的最简单的方法就是在用户控件的指令中以声明方式使用新的ProviderName属性。
下面,我们将在MyOutputCacheProviderUserControl用户控件里定义该输出缓存提供程序,如下面的代码所示:
代码如下 | 复制代码 |
<%@ Control Language="C#" AutoEventWireup="true"
public partial class MyOutputCacheProviderUserControl :System.Web.UI.UserControl |
定义好MyOutputCacheProviderUserControl用户控件之后,下面我们继续来定义一个测试页面MyOutputCacheProviderWebForm.aspx,代码如下所示:
代码如下 | 复制代码 |
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MyOutputCacheProviderWebForm.aspx.cs" MyOutputCacheProviderWebForm.aspx.cs代码如下所示: public partial class MyOutputCacheProviderWebForm : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { this.Label1.Text=DateTime.Now.ToLongTimeString(); } } |
运行MyOutputCacheProviderWebForm.aspx页面,结果如图19-5所示:
图19-5:示例运行结果
打开“C:Cache”文件夹,你就能够看见所生成的缓存文件,如图19-6与19-7所示:
图19-6:在本地磁盘生成的缓存文件
图19-7:缓存文件内容
这里需要注意的是,你只能在用户控件中指定@ OutputCache指令的ProviderName属性,但在ASPX页面是不允许你指定@ OutputCache指令的ProviderName属性的。因为在页面中,默认情况下会使用web.config中配置的defaultProvider。
虽然你不能够以声明的方式指定@ OutputCache指令的ProviderName属性,但你可以在Global.asax文件中通过重载GetOutputCacheProviderName(HttpContext context)方法以编程方式指定针对一个具体的请求使用哪一个提供程序。如下面的代码所示:public override string GetOutputCacheProviderName(HttpContext context)
代码如下 | 复制代码 |
{ if (context.Request.Path.EndsWith("MyOutputCacheProviderWebForm.aspx")) { return "MyOutputCacheProvider"; } else { return base.GetOutputCacheProviderName(context); } } |
利用ASP.NET 4中增加的输出缓存提供程序扩展,你现在可以为你的Web站点采取更积极和更智能化的输出缓存策略。例如,你可以把一个网站中的用户访问量占“前十名”的那些网页缓存到内存中,而把那些较低访问量的网页缓存到磁盘上