ASP.NET MVC编程——缓存
Web缓存分为服务端缓存和客户端缓存。
1 服务端缓存
1.1请求域内的缓存:HttpContext.Items
类型:
HttpContext.Items的类型为IDictionary,且键和值都是object类型
访问性:
只存在于当前请求范围内。
例:
HttpContext.Items["key"] ="value"; var value = HttpContext.Items["key"];
1.2用户域内的缓存:HttpContext.Session
类型:
HttpContext.Session的类型为HttpSessionStateBase,这个类继承自ICollection, IEnumerable,
访问性:
只针对当前用户有效,无法跨用户级别访问。
过期设置:
设置过期时间,当过期时间到达时,服务器便销毁存储在Session里的对象。
例:
HttpContext.Session["key"] = "value"; var value = (string)HttpContext.Session["key"]; //设置超时时间为20分钟 HttpContext.Session.Timeout = 20;
或配置 <system.web> <sessionState timeout="20" /> </system.web>
1.3应用程序域内的缓存:HttpContext.Application,HttpContext.Cache
类型:
HttpContext.Application类型为HttpApplicationStateBase,此类继承自NameObjectCollectionBase, ICollection, IEnumerableHttpContext.Cache为Cache类型,此类继承自IEnumerable
访问性:
他们的生命周期和IIS工作进程一样长,但HttpContext.Cache不能跨工作进程。
过期机制:
HttpContext.Cache可以对缓存数据设置过期机制,有两种方式:一是最后一次访问之后多长时间过期,另一种是设定过期时间点。这两种过期策略不能同时使用。
缓存依赖:
Cache提供了下面的方法来设置缓存依赖
public object Add(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback)
或者添加值的时候设置缓存依赖:
public void Insert(string key, object value, CacheDependency dependencies);
其中我们可以通过dependencies参数指定依赖的策略。
例:
HttpContext.Application["key"] = "value"; var value = (string)HttpContext.Application["key"]; HttpContext.Cache["key"] = "value"; var value = (string)HttpContext.Cache["key"];
1.4输出缓存
使用OutputCacheAttribute属性将控制器操作渲染的操作结果保存到缓存过滤器。可以利用它实现甜甜圈洞缓存,即缓存部分内容,而允许外围数据变化。使用此特性的时候要注意:子操作的 OutputCacheAttribute 仅支持 Duration、VaryByCustom 和 VaryByParam 值。不能为子操作设置 CacheProfile、Location、NoStore、SqlDependency、VaryByContentEncoding 或 VaryByHeader 值,否则会抛出异常。
下面是该特性的定义。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public class OutputCacheAttribute : ActionFilterAttribute, IExceptionFilter { //获取或设置缓存持续时间(以秒为单位) public int Duration { get; set; } //获取或设置数据存储位置 public OutputCacheLocation Location { get; set; } //是否存储缓存 public bool NoStore { get; set; } //获取或设置基于参数变化的值 public string VaryByParam { get; set; } }
缓存位置枚举值为:
public enum OutputCacheLocation { //输出缓存可位于产生请求的浏览器客户端、参与请求的代理服务器(或任何其他服务器)或处理请求的服务器上。 此值对应于 System.Web.HttpCacheability.Public枚举值。 Any = 0, //输出缓存位于产生请求的浏览器客户端上。 此值对应于System.Web.HttpCacheability.Private 枚举值。 Client = 1, //输出缓存可存储在任何 HTTP 1.1 可缓存设备中,源服务器除外。 这包括代理服务器和发出请求的客户端。 Downstream = 2, //输出缓存位于处理请求的 Web 服务器上。 此值对应于 System.Web.HttpCacheability.Server 枚举值。 Server = 3, //对于请求的页,禁用输出缓存。 此值对应于 System.Web.HttpCacheability.NoCache 枚举值。 None = 4, //输出缓存只能存储在源服务器或发出请求的客户端中。 代理服务器不能缓存响应。 此值对应于 System.Web.HttpCacheability.Private和 System.Web.HttpCacheability.Server 枚举值的组合。 ServerAndClient = 5, }
例:
控制器Home的CacheExe操作为:
[OutputCache(Duration=20)] public ActionResult CacheExe() { ViewBag.TimeNow = DateTime.Now.ToString("yyyyMMdd hh:mm:ss"); return View(); }
视图Index.cshtml为:
<div class="jumbotron"> <h1>ASP.NET</h1> <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p> <p><a href="http://asp.net" class="btn btn-primary btn-lg">Learn more »</a></p> </div> <div class=”part”> @Html.Action("CacheExe") </div> <div class="row"> ...... </div>
视图CacheExe.cshtml为:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title></title> </head> <body> <div> <h1>@ViewBag.TimeNow</h1> </div> </body> </html>
分析:
当渲染页面时,class为part的<div>部分从缓存中取值,其他部分动态变化。由于CacheExe操作每调用一次就会计算一次当前时间,并将其付给ViewBag.TimeNow,那么如果在20s内刷新一次页面,显示的时间不变的话,就如我们设想的那样,系统将子操作调用的视图缓存了起来,过期时间为这里设置的20s
1.5甜甜圈缓存
只缓存页面的外围部分,允许一部分内容动态变化。
ASP.NET MVC 不支持甜甜圈缓存,使用MvcDonutCachingNuGet包扩展了HTML方法,支持这种缓存方式。
2客户端缓存
浏览器缓存
浏览器将从服务器获取的资源保存到本地,然后当再次发起请求并且请求url与以往请求url之一相同时,浏览器会优先查看本地磁盘,加载本地缓存资源。如果请求url不同,那么浏览器会获取网络资源。
在服务器端设置http消息头
常用设置举例:
//设置是否可被客户端或代理缓存 Response.Cache.SetCacheability(HttpCacheability.Public); //设置过期时间 Response.Cache.SetMaxAge(TimeSpan.FromMinutes(30)); //设置绝对过期时间 Response.Cache.SetExpires(DateTime.Now.AddMinutes(30));
验证缓存数据的有效性
通过服务端对http消息头进行设置,以便客户端可以验证数据有效性。
常用设置举例:
//设置Last-Modified HTTP标头 Response.Cache.SetLastModified(DateTime.Now); //设置ETag HTTP标头 Response.Cache.SetETag(@"uni:version");