Filter(筛选器)是基于AOP(面向方面编程)的设计,它的作用是Actionr的执行注入额外的逻辑,以达到横切注入的目的。

IFilter

在WebAPI中所以的Filter都实现了IFilter接口 ,IFilter接口只有一个只读属性AllowMultiple,它表示同类的Filter是否可以应用到同一目标对象上。

public interface IFilter

{ 

bool AllowMultiple { get; } 

 }

FilterInfo

在HttpActionDescriptor与HttpControllerDescriptor中也存储了Action使用到的Filter。但它不是直接以IFilter的形式进行存储,也是以FilterInfo(System.Web.Http.Filters)。

public sealed class FilterInfo

 {

public FilterInfo(IFilter instance, FilterScope scope); 

public IFilter Instance { get; } 

public FilterScope Scope { get; } 

 }

在FilterInfo中有两个属性:Instance,Scope。其中Instance是IFilter对象。在实际对Filter运用中我们应该注意并发的情况,因为对于同一个Filter调用的都是同一个Filter对象。

FilterScope

对于FilterInfo类的Scope属性,它表示Filter的域。在WebAPI中Filter有3个域:Global,Controller,Action。

public enum FilterScope

 { 

 Global = 0, 

 Controller = 10, 

 Action = 20, 

 }

对于Controller,Action的Filter添加都是采用特性(Attribute)的方式。对于全局Filter是添加在HttpConfiguration的Filter。

FilterProvider

WebAPI提供了IFilterProvider(System.Web.Http.Filters)用于提供不同域下的Filter。

public interface IFilterProvider

{

IEnumerable<FilterInfo> GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor); 

 }

在WebAPI中FilterProvider也是"标准化组件",但是它是以multi的形式注入的.WebAPI中IFilter有两个默认实现: ConfigurationFilterProvider, ActionDescriptorFilterProvider,从命名上我们就可以知道前者是提供全局Filter,后者是提供Controller,Action的Filter。

5类Filter

WebAPI为我们定义了5类Filter。分别如下:

AuthenticationFilter:用于请求认证(IAuthenticationFilter)。

AuthorizationFilter:用于请求授权(IAuthorizationFilter)。

ActionFilter:ActionFilter:注册的操作会在Action执行的前后被调用(IActionFilter)。

ExceptionFilter:当目标Action抛出异常是调用(IExceptionFilter)。

OverrideFilter:用于屏蔽当前域之前的Filter(IOverrideFilter)。

本文重点讲后三类Filter,对于前两类,后续再做跟进。对于后三类Filter默认实现是ActionFilterAttribute,ExceptionFilterAttribute,OverrideActionFilterAttribute。如下:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 

public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IFilter

 {

protected ActionFilterAttribute(); 

public virtual void OnActionExecuted(HttpActionExecutedContext actionExecutedContext); 

public virtual Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken); 

public virtual void OnActionExecuting(HttpActionContext actionContext); 

public virtual Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken); 

 }
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] 

public abstract class ExceptionFilterAttribute : FilterAttribute, IExceptionFilter, IFilter

 { 

protected ExceptionFilterAttribute(); 

public virtual void OnException(HttpActionExecutedContext actionExecutedContext); 

public virtual Task OnExceptionAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken); 

 }
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 

public sealed class OverrideActionFiltersAttribute : Attribute, IOverrideFilter, IFilter

 { 

public OverrideActionFiltersAttribute(); 

public Type FiltersToOverride { get; } 

 }

唯一性

因为Filter有三个域,那么在采用特性标示的方式注入Filter的,必定有可能会对同一个Action上注入多个相同的Filter。显然在使用中一般不会允许这种情况发生。WebAPI中提供了相应的策略用来保证Filter的唯一性。即对FilterAttribute添加AttributeUsage特性,并将AllowMultiple设置为false.

当然这个设置过后你会发现在三个域上我还是可以添加相同的Filter,那么这个时候WebAPI会为我们筛选出一个Filter去调用。筛选规则如下:

Action>Controller>Global

即FilterScope的值越大,优先级超高。

ActionFilter

ActionFilterAttribute提供了4个虚方法: OnActionExecuted,OnActionExecutedAsync,OnActionExecuting,OnActionExecutingAsync 其实两个异步方法只是对两个同步的方法的封装,所以我们一般只重写两个同步方法。

在执行顺序上ActionFilter的规则是:

  1. 不同域:Global>ControllerAction
  2. 相同域:按照注入顺序执行

在执行OnActionExecuting的过程中如果给actionContext.Response赋值,那么Filter管道就会做返回处理,不再去做后续操作。

ExceptionFilter

在执行Action与整个ActionFilter管道中,如果抛出异常,

  1. ExpceptionFilter的执行顺序与ActionFilter正好相反
  2. ExceptionFilter管道处理的是整个ActionFilter管道抛出的异常,并不是单纯的Action抛出的异常
  3. 如果在ExceptionFilter管道中抛出异常,那么该ExceptionFilter都不会执行。

OverrideFilter

一个Action的所有Filter是Global,Controller,Action三个域下的Filter的总合,但有些时候我们并想要上一级域的Filter这个时候就需要用到OverrideFilter。WebAPI的OverrideActionFiltersAttribute只会屏蔽IActionFilter,并不会对其它的Filter进行屏蔽。

源码

Github: https://github.com/BarlowDu/WebAPI (API_13)

ASP.NET WebAPI 13 Filter的更多相关文章

  1. Asp.Net WebAPI中Filter过滤器的使用以及执行顺序

    转发自:http://www.cnblogs.com/UliiAn/p/5402146.html 在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行 ...

  2. ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver

    ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver   Message WebAPI作为通信架构必定包含包含请求与响应两个方法 ...

  3. ASP.NET WEBAPI 的身份验证和授权

    定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...

  4. 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi

    一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...

  5. 让Asp.Net WebAPI支持OData查询,排序,过滤。

    让Asp.Net WebAPI支持OData后,就能支持在url中直接输入排序,过滤条件了. 一.创建Asp.Net WebAPI项目: 二.使用NuGet安装Asp.Net WebAPI 2.2和O ...

  6. 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性

    [索引页][源码下载] 返璞归真 asp.net mvc (13) - asp.net mvc 5.0 新特性 作者:webabcd 介绍asp.net mvc 之 asp.net mvc 5.0 新 ...

  7. 使用ASP.Net WebAPI构建REST服务(三)——返回值

    Asp.Net WebAPI服务函数的返回值主要可以分为void.普通对象.HttpResponseMessag.IHttpActionResult e四种,本文这里简单的介绍一下它们的区别. 一.返 ...

  8. 前端angularjs+requirejs+dhtmlx 后端asp.net webapi

    享一个前后端分离方案源码-前端angularjs+requirejs+dhtmlx 后端asp.net webapi   一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家 ...

  9. Asp.Net WebApi Swagger终极搭建

    [PS:原文手打,转载说明出处,博客园] 关于为什么用Swagger 目前稍微有点规模的公司,已经从原先的瀑布流开发到了敏捷开发,实现前后端分离,为此后端工程师只关注写好Api即可,那程序员最讨厌的就 ...

随机推荐

  1. Android Weak Handler:可以避免内存泄漏的Handler库

    这是一个针对技术开发者的一个应用,你可以在掘金上获取最新最优质的技术干货,不仅仅是Android知识.前端.后端以至于产品和设计都有涉猎,想成为全栈工程师的朋友不要错过! android使用java作 ...

  2. 分享7款非常实用的jQuery/CSS3插件演示和源码

    上次我们分享了15款效果很酷的最新jQuery/CSS3特效,非常不错,今天要分享7个非常实用的jQuery/CSS3插件演示和源码,一起来看看. 1.jQuery ajax点击地图显示商家网点分布 ...

  3. 免费国内外"代码托管服务器"收集

      国内 开源中国  http://git.oschina.net/  支持git 淘宝code  http://code.taobao.org/  支持svn 京东code  https://cod ...

  4. IOS 使用SDWebImage实现仿新浪微博照片浏览器

    使用第三方库SDWebImage实现仿新浪微博照片浏览器,可以下载图片缓存,点击之后滚动查看相片,具体效果如下: 代码如下: WeiboImageView.h: #import <UIKit/U ...

  5. Ubuntu下的防火墙

    Ubuntu下的防火墙Gufw-ufw Gufw是ufw的桌面版本,网上有Gufw的安装和配置方法,但是我认为并不是很好.网上的教程也有点愚弄大众的嫌疑,因为按照他的说法,最后防火墙根本就无法自动启动 ...

  6. IDL中histogram的应用

    前面一段时间在使用Histogram时一直是不能更好的理解其中的奥秘,通过阅读帮助以及查看相应的文档,终于理解了其中的玄机,很多时候是因为在学习的时候英文不知道翻译成什么样的内容比较合理,这样就给后面 ...

  7. [转载]浅谈组策略设置IE受信任站点

    在企业中,通常会有一些业务系统,要求必须加入到客户端IE受信任站点,才能完全正常运行访问,在没有域的情况下,可能要通过管理员手动设置,或者通过其它网络推送方法来设置. 有了域之后,这项工作就可以很好的 ...

  8. SQL Server技术问题之存储过程与sql语句的优缺点

    优点: 1. 允许模块化程序设计.2.可维护性高,只需创建存储过程一次并将其存储在数据库中,以后即可在程序中调用该过程任意次.存储过程可独立于程序源代码而单独修改,而不需要更改.测试以及重新部署程序集 ...

  9. 通过Foxit和坚果云实现iPad和PC的pdf同步阅读(修改,笔记)

    这是解决我之后上班地铁上看书问题的一个关键部分 一个手持电子设备,不大不小 一个方便做笔记的笔 一个方便做笔记的阅读器软件 方便快速地同步(只同步标记最好了) 在查看很多建议以及自己尝试之后,总结了这 ...

  10. 【Coding地址汇总】2016年沈航软工学生项目主页

    同学们把自己的coding主页链接贴在评论里,要求格式"班号+学号+coding主页链接",如: "1301+13061193 + https://coding.net/ ...