MVC3里的AOP实现

来源:互联网 发布:淘宝知识产权注册流程 编辑:程序博客网 时间:2024/06/09 21:02

Filter即是AOP实现

有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你创建action过滤器。Action过滤器是自定义的Attributes,用来标记添加Action方法之前或者Action方法之后的行为到控制器类中的Action方法中。

一些可能用到Action过滤器的地方有:

  • 日志,异常处理
  • 身份验证和授权 - 限制用户的访问
  • 输出缓存 - 保存一个Action的结果
  • 网络爬虫的过滤
  • 本地化
  • 动态Action - 将一个Action注入到控制器中

ASP.NET MVC为我们提供了下面的几个Filter接口:

  • IActionFilter
  • IAuthorizationFilter
  • IExceptionFilter
  • IResultFilter

要实现一个Filter,我们需要继承自FilterAttribute类同时实现上面的一个或几个接口:

public class MyFilter : FilterAttribute, IActionFilter, IResultFilter
{
}
复制代码

这几个接口提供的方法如下:

image

上图的方法和Filter接口对应的方法按名称对号入座就可以。

IActionFilter接口有两个方法:

image

其中OnActionExecuting在执行Action方法之前会被调用(AOP里称前置通知),OnActionExecuted会在Action方法执行后调用(AOP里称后置通知)。注意他们的参数分别是ActionExecutingContext和ActionExecutedContext。

ActionExecutedContext类包含一个 Canceled的属性,允许你取消当前的Action(怎么原来在P3中是在ActionExecutingContext的Canceled属性在P5中没有了呢?神奇.那么在OnActionExecuting的时候怎么取消一个Action呢?)。

FilterExcutedContext 类包含一个Exception属性和一个ExceptionHandled属性。如果Exception属性为null,则没有异常在action stack中,表明Action方法运行并没有发生错误。反之则为出现异常。如果将ExceptionHandled属性设置为true则表明在这个Filter中已经处理了异常。

IResultFilter接口也提供了两个方法:

image

他们分别在Action返回结果(例如return View();)之前和之后执行。和IActionFilter差不多就不多说了。

IAuthorizationFilter是一个用于身份验证的Filter。只提供了一个void OnAuthorization(AuthorizationContext filterContext)方法。

IExceptionFilter会在出现异常的时候调用,也是只 提供一个void OnException(ExceptionContext filterContext)的方法;

这些Filter可以被应用在类或者方法上,下面我们来看一下他们的执行顺序。首先我们写一个BaseController并加上两个Filter:

[MyFilter2(Target = "BaseController")]
[MyFilter1(Target
="BaseController")]
public class BaseController : Controller
{
}
复制代码

应为Controller类是实现这几个Filter接口的,所以我们在HomeController中重写Controller基类中的所有Filter接口的方法,并在HomeController类和里面的Filter方法加上我们自定义的MyFilter:


[MyFilter2(Target = "HomeController")]
//[MyFilter1(Target = "HomeController")]//注意我在这里把MyFilter1注释了.
[HandleError]
public class HomeController : BaseController
{
    [MyFilter2(Target
= "HomeController.Filter")]
    [MyFilter1(Target
= "HomeController.Filter")]
   
public ActionResult Filter()
    {
       
return Content("<div>这是在Action方法里面返回的内容!</div>");
    }

   
protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write(
"<div>这是在HomeController里面重写OnActionExecuted方法添加的内容!</div>");
    }

   
protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write(
"<div>这是在HomeController里面重写OnActionExecuting方法添加的内容!</div>");
    }

   
protected override void OnAuthorization(AuthorizationContext filterContext)
    {
        filterContext.HttpContext.Response.Write(
"<div>这是在HomeController里面重写OnAuthorization方法添加的内容!</div>");
    }

   
protected override void OnException(ExceptionContext filterContext)
    {
        filterContext.HttpContext.Response.Write(
"<div>这是在HomeController里面重写OnException方法添加的内容!</div>");
        filterContext.ExceptionHandled
= true;
    }

   
protected override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write(
"<div>这是在HomeController里面重写OnResultExecuted方法添加的内容!</div>");
    }

   
protected override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write(
"<div>这是在HomeController里面重写OnResultExecuting方法添加的内容!</div>");
    }
}
复制代码

然后我们运行一下看看结果如何:

image

从运行结果我们可以看到,在Controller中重写的Filter会最先执行,然后到应用在类上的Filter,然后再到应用在类方法上的Filter。

而4个接口的方法执行顺序如下:IAuthorizationFilter -> IActionFilter ->IResultFilter -> IExceptionFilter .

而对于同一个Filter,例如IAuthorizationFilter在MyFilter1和MyFilter2里里面的实现,又根据他们的加载顺序不同而不同。

在BaseController中应用的Filter会被子类继承,如果子类又应用了和基类同样的Filter,则会不执行基类的Filter。例如上面的HomeController应用了MyFilter2,所以调用HomeController的MyFilter2,而不是BaseController的MyFilter2。

这个执行顺序还得大家好好研究才能了解的。

同时FilterAttribute还提供了一个Order的属性,用于指定Filter的执行顺序。

每一个Action过滤器都有一个 Order 属性,用来决定Action过滤器在该范围内的执行顺序。Order属性必需是0(默认值)或者更大的整数值。省略Order属性则会给该过滤器的Order值为 -1, 表明未指明顺序。任何一个在同一范围的Action过滤器Order设为 -1 的都将按不确定的顺序执行,但在此之前过滤器有一个特定的顺序(请参考上图).

当设置Order属性的值的时候,必需指定一个唯一的值。如果两个或者更多的Action过滤器具有相同的Order属性值,将会抛出一个异常。

来看一个示例:

[Filter1(Order = 2)]
[Filter2(Order
= 3)]
[Filter3(Order
= 1)]
public void Index()
{
    RenderView(
"Index");
}
复制代码

Filter的执行顺序为:Filter3 => Filter1 => Filter2. 参考:ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)

三 ASP.NET MVC3  全局过滤器

ASP.NET MVC 支持通过过滤机制来描述性地应用“横切”逻辑。 你可以使用属性语法为控制器和执行函数指定过滤器,如下所示

image

但在使用中,我们常常希望将一些过滤器逻辑应用于程序中的所有控制器上,如Authorize过滤器。

现在ASP.NET MVC3 能够让你指定一个全局的过滤器,这个过滤器可以应用于程序中的所有控制器上。

如下图所示:在Global文件中将自定义过滤器加入GlobalFliterCollection中就可以了

image

在MVC3中,这个过滤器的判定逻辑非常灵活,你可以配置一个全局过滤器,使它只在某些条件符合的时候才启用。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕妇肛裂拉屎疼怎么办 产后50天小肚子突出怎么办 肚子像怀孕一样大怎么办 蹲厕所拉不出来怎么办 生气导致回奶了怎么办 老公每晚要吃奶才睡觉怎么办 分分钟想把老公杀掉怎么办 老公出轨闹的厉害离家出走怎么办? 儿子故意杀人一审判死刑怎么办 被家暴时妻子杀了丈夫该怎么办 丈夫挣钱不给妻子怎么办 白色皮鞋染了色怎么办 刺扎到手里拿不出来怎么办 军官证解锁片丢了怎么办 六安市人民医院药品停用了怎么办 信无法寄到该怎么办 5个月的宝宝光有屎沫怎么办 胸牌的别针坏了怎么办 工资表税金扣多了怎么办? 装修公司不发放工程怎么办 公司不给开收入证明怎么办 装修公司不付工人工资怎么办 收入证明少500元怎么办 dnf二级输错了怎么办 如果受到法律的伤害怎么办 86岁了还怕死怎么办 风衣的腰带丢了怎么办 成为伪娘身上的毛怎么办 军官升不上去了怎么办 王者荣耀代练封号怎么办 cf淘宝代练封号怎么办 买音乐会的票过期怎么办 十年多年前被怨错拘留了怎么办 与室友关系闹僵怎么办 开庭后被告威胁我们证人怎么办 开车撞了豪车怎么办 我把人撞了全责怎么办 开车撞伤人没钱赔怎么办 开车撞伤无证驾驶人怎么办 开车把人撞伤了只买交强险怎么办 开车撞伤人赔不起怎么办