缓存[ASP.NET MVC2 系列] Action Filters以及自定义OutputCache ActionFilterAttribute事件发生次序

outputcache  时间:2021-04-18  阅读:()

[ASP.NET MVC2系列] Action Filters以及自定义OutputCache

ActionFilterAttribute事件发生次序

[ASP.NET MVC2系列]

[ASP.NET MVC2系列] ASP.Net MVC教程之《在15分钟内用ASP.Net MVC创建一个电影数据库应用程序》

[ASP.NET MVC2系列] ASP.Net MVC教程之《ASP.NET MVC概述》

[ASP.NET MVC2系列]理解MVC应用程序的执行过程

[ASP.NET MVC2系列] ASP.NET MVC Routing概述

[ASP.NET MVC2系列] ASP.NET MVC之如何创建自定义路由约束

[ASP.NET MVC2系列] Action要求与View本质

[ASP.NET MVC2系列] Action Filters以及自定义OutputCacheActionFilterAttribute事件发生次序

理解Action Filters

Action filter是能够应用于controller action --或整个controller的一个特性它们的基类为System.Web.Mvc.FilterAttribute 。它限定了action执行的方式。 ASP.NET MVC框架包含数个action filters。

 HandleError –这个action过滤器处理controller action执行时出

现的错误。

 OutputCache –这个action过滤器将controller action的输出缓存

一段制定的时间.

 Authorize –这个action过滤器使你能够限制特定的用户或角色的访

问.

使用Action Filteraction filter是一个特性.你能够应用大部分的action filters在单个的controller action或者整个controller上.

例如下面的Data controller有一个返回当前时间的Index()方法.这个action拥有OutputCache action filter.这个过滤器导致由action返回的值能够缓存10秒钟.

VaryByParam属性使用的设置不建议通过设置“*”的值来使用所有参数进行区分。这可能会导致缓存溢出。

public class DataController : Controller

{

//

// GET: /Data/

[OutputCache(Duration = 20,VaryByParam ="") ]public string Index()

{return DateTime.Now.ToString() ;

}

}

如果你重复调用Index() action 不断刷新当前页面 ,那么你将看到当前的内容在Duration = 20秒内是不变的.

一个单一的action filter – OutputCache action filter –被应用于Index()方法. 同样你可以应用多个action filters在同一个action上.不同类型的Filters

ASP.NET MVC框架支持多种不同类型的过滤器:

1. Authorization filters –实现IAuthorizationFilter特性.

2. Action filters –实现IActionFilter特性.

3. Result filters –实现IResultFilter特性.

4. Exception filters –实现IExceptionFilter特性.

Filters按照上面列出的顺序执行。例如, authorization filters总是在action filters之前执行 exception filters在所有其他类型的filter之后执行.

ActionFilterAttribute基类

为了使你能够更加容易的实现自定义的action filter, ASP.NET MVC框架包含一个ActionFilterAttribute基类.这个类实现了IActionFilter与

IResultFilter接口并且继承了Filter类。

ActionFilterAttribute基类拥有以下可以重载的方法:

 OnActionExecuting在action method调用前发生。

 OnActionExecuted在action method调用后发生,但是在result执行

前发生(在view呈现前)

 OnResultExecuting在result执行前发生(在view呈现前)

 OnResultExecuted在result执行后发生(在view呈现后)

创建一个ASP.NET MVC OutputCache ActionFilterAttribute在每一个web应用程序中,有的情况下,你想在一段时间内缓存一个具体的页面HTML输出,因为相关的数据和处理并不是总是变化。这种缓存的响应是储存在服务器的内存中。因为没有必要的额外处理它提供了非常快速的响应。使用经典的ASP.NET你可以在.aspx页面上使用OutputCache指令它告诉ASP.NET运行时在某一特定的时间段内来缓存响应数据。缓存可随参数而改变,这将导致产生依赖于参数的不同缓存响应。作为一个额外的功能,还可以发送一些HTTP头到客户端。在一段时间以内客户端从浏览器缓存中加载页面。大的优势是你的web服务器将接收更少的客户端要求,因为他们仅仅是使用他们自己的缓存。

使用ASP.NET MVC框架,简单的指定OutputCache指令并不能达到理想的效果.幸好, ActionFilterAttribute让你能够在controller action执行的前后运行代码.

让我们使用类似的方法来创建OutputCache ActionFilterAttribute。

[OutputCache(Duration = 60, VaryByParam = "*", CachePolicy = CachePolicy.Server) ]public ActionResult Index()

{

// . . .

}

我们将使用命名为Ca ch ePoli cy的枚举类型来指定Ou tpu tCa ch e特性应怎样以及在哪里进行缓存:public enum CachePolicy

{

NoCache = 0,

Client = 1,

Server = 2,

ClientAndServer = 3

}

1.实现client-side缓存

事实上,这是很容易的。在view呈现前,我们将增加一些HTTP头到响应流。 网页浏览器将获得这些头部并且通过使用正确的缓存设置来回应请求。如果我们设置duration为60,浏览器将首页缓存一分钟。using System.Web.Mvc;namespace MVCActionFilters.Web.Models

{public class OutputCache:System.Web.Mvc.ActionFilterAttribute

{public int Duration { get; set; }public CachePolicy CachePolicy { get; set; }public override void OnActionExecuted(ActionExecutedContext filterContext)

{if (CachePolicy == CachePolicy.Client | | CachePolicy == CachePolicy.ClientAndServer)

{if (Duration <= 0) return;

//用于设置特定于缓存的HTTP标头以及用于控

制ASP.NET页输出缓存

HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;

TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration) ;cache.SetCacheability(HttpCacheability.Public) ;cache.SetExpires(DateTime.Now.Add(cacheDuration) ) ;cache.SetMaxAge(cacheDuration) ;cache.AppendCacheExtension("must-revalidate, proxy-revalidate") ;

}

}

}

}

2. 实现server-side缓存

Server-side缓存有一点难度.首要的,在输出缓存系统中我们将不得不准备HTTP响应为可读的。为了这样做我们首先保存当前的HTTP context到类的一个变量中.然后,我们创建一个新的httpcontext 通过它将数据写入StringWri t er 同时允许读操作可以发生:existingContext = System.Web.HttpContext.Current;//保存当前的HTTPcontext到类的一个变量中writer = new StringWriter() ;

HttpResponse response = new HttpResponse(writer) ;

HttpContext context = new HttpContext(existingContext.Request, response)

{

User = existingContext.User

} ;

System.Web.HttpContext.Current = context;public override void OnResultExecuting(ResultExecutingContext filterContext)

{if (CachePolicy == CachePolicy.Server | | CachePolicy == CachePolicy.ClientAndServer)

{

//获取缓存实例cache = filterContext.HttpContext.Cache;

//获取缓存数据object cachedData = cache.Get(GenerateKey(filterContext) ) ;if (cachedData != null)

{

//返回缓存数据cacheHit = true;filterContext.HttpContext.Response.Write(cachedData) ;filterContext.Cancel = true;

}else

{ //重新设置缓存数据existingContext = System.Web.HttpContext.Current;writer = new StringWriter() ;

HttpResponse response = new HttpResponse(writer) ;

HttpContext context = new HttpContext(existingContext.Request, response)

{

User = existingContext.User

} ;foreach (var key in existingContext. Items.Keys)

{context. Items[key] = existingContext. Items[key] ;

}

System.Web.HttpContext.Current = context;

}

}

}

利用该代码,我们能从高速缓存中检索现有项,并设置了HTTP响应能够被读取。在视图呈现之后将数据存储在高速缓存中:public override void OnResultExecuted(ResultExecutedContext filterContext)

{

//服务器端缓存?if (CachePolicy == CachePolicy.Server | | CachePolicy == CachePolicy.ClientAndServer)

{if (!cacheHit)

{

//存储原有的context

System.Web.HttpContext.Current = existingContext;

//返回呈现的数据existingContext.Response.Write(writer.ToString() ) ;

//增加数据到缓存cache.Add(

GenerateKey(filterContext) ,writer.ToString() ,nul l,

DateTime.Now.AddSeconds(Duration) ,

Cache.NoSlidingExpiration,

CacheItemPriority.Normal,nul l) ;

}

}

}

你现在注意到添加了一个VaryByParam到OutputCache

ActionFilterAttribute。当缓存server-side时,我可以通过传入的参数来改变缓存存储。这个GenerateKey方法会产生一个依赖于controller,action和VaryByParam的键。private string GenerateKey(ControllerContext filterContext)

{

StringBuilder cacheKey = new StringBuilder() ;

// Controller + actioncacheKey.Append(filterContext.Controller.GetType() .FullName) ;if (filterContext.RouteData.Values.ContainsKey("action") )

{cacheKey.Append("_") ;cacheKey.Append(filterContext.RouteData.Values["action"] .ToString() ) ;

}

// Variation by parameters

List<string> varyByParam = VaryByParam.Split(' ; ' ) .ToList() ;if (!string. IsNullOrEmpty(VaryByParam) )

{foreach (KeyValuePair<string, object> pair in filterContext.RouteData.Values)

{if (VaryByParam == "*" | | varyByParam.Contains(pair.Key) )

{cacheKey.Append("_") ;cacheKey.Append(pair.Key) ;cacheKey.Append("=") ;cacheKey.Append(pair.Value.ToString() ) ;

}

}

}return cacheKey.ToString() ;

}

现在你可以增加OutputCache attribute到应用程序的任何一个controller与controller action中。

[MVCActionFilters.Web.Common.OutputCache(Duration = 20, VaryByParam= "*",CachePolicy=Common.CachePolicy.Client) ]public string Cache()

{return DateTime.Now.ToString() ;

}

设置CachePolicy为Common.CachePolicy.Client时将直接在客户端缓存中读取数据。

总结

需注意事件的发生时间段

 OnActionExecuting在action method调用前发生。

 OnActionExecuted在action method调用后发生,但是在result执行前发生(在view呈现前)

 OnResultExecuting在result执行前发生(在view呈现前)

 OnResultExecuted在result执行后发生(在view呈现后)

源代码下载 MVCActionFilters.rarTag标签: ASP.NET MVC,ASP.NET,Cache

VirMach:$27.3/月-E3-1240v1/16GB/1TB/10TB/洛杉矶等多机房

上次部落分享过VirMach提供的End of Life Plans系列的VPS主机,最近他们又发布了DEDICATED MIGRATION SPECIALS产品,并提供6.5-7.5折优惠码,优惠后最低每月27.3美元起。同样的这些机器现在订购,将在2021年9月30日至2022年4月30日之间迁移,目前这些等待迁移机器可以在洛杉矶、达拉斯、亚特兰大、纽约、芝加哥等5个地区机房开设,未来迁移的时...

ReadyDedis:VPS全场5折,1G内存套餐月付2美元起,8个机房可选_服务器安装svn

ReadyDedis是一家2018年成立的国外VPS商家,由印度人开设,主要提供VPS和独立服务器租用等,可选数据中心包括美国洛杉矶、西雅图、亚特兰大、纽约、拉斯维加斯、杰克逊维尔、印度和德国等。目前,商家针对全部VPS主机提供新年5折优惠码,优惠后最低套餐1GB内存每月仅需2美元起,所有VPS均为1Gbps端口不限流量方式。下面列出几款主机配置信息。CPU:1core内存:1GB硬盘:25GB ...

无忧云-河南洛阳BGP,CEPH集群分布式存储,数据安全可靠,活动期间月付大优惠!

 无忧云怎么样?无忧云服务器好不好?无忧云值不值得购买?无忧云是一家成立于2017年的老牌商家旗下的服务器销售品牌,现由深圳市云上无忧网络科技有限公司运营,是正规持证IDC/ISP/IRCS商家,主要销售国内、中国香港、国外服务器产品,线路有腾讯云国外线路、自营香港CN2线路等,都是中国大陆直连线路,非常适合免备案建站业务需求和各种负载较高的项目,同时国内服务器也有多个BGP以及高防节点...

outputcache为你推荐
229.254route内存nod32支出127支持ipadcss3圆角用CSS3怎么实现圆角边框?tcpip上的netbios禁用tcp/ip上的netbios对网络应用软件的正常运行有没有影响?重庆电信宽带管家电信的宽带上网助手是什么?联通iphone4iphone4想换联通的卡 是普通联通的卡都能开通3G么 还是得换联通3G卡 联通都有什么套餐 我是北京的迅雷下载速度迅雷限制下载速度要设置多少routeadd如何用route add添加本地路由表,使一个网段的机器能访问另一个网段局域网的机器。望高手指点。
naning9韩国官网 老鹰主机 百度云100as 香港托管 68.168.16.150 国内php空间 个人域名 有奖调查 佛山高防服务器 免费高速空间 息壤代理 服务器论坛 可外链的相册 ssl加速 阿里云邮箱个人版 phpwind论坛 weblogic部署 饭桶 linux命令vi 挂马检测工具 更多