ASP.NET WebAPI 13 Filter
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的规则是:
- 不同域:Global>ControllerAction
- 相同域:按照注入顺序执行
在执行OnActionExecuting的过程中如果给actionContext.Response赋值,那么Filter管道就会做返回处理,不再去做后续操作。
ExceptionFilter
在执行Action与整个ActionFilter管道中,如果抛出异常,
- ExpceptionFilter的执行顺序与ActionFilter正好相反
- ExceptionFilter管道处理的是整个ActionFilter管道抛出的异常,并不是单纯的Action抛出的异常
- 如果在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的更多相关文章
- Asp.Net WebAPI中Filter过滤器的使用以及执行顺序
转发自:http://www.cnblogs.com/UliiAn/p/5402146.html 在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行 ...
- ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver
ASP.NET WebAPI 08 Message,HttpConfiguration,DependencyResolver Message WebAPI作为通信架构必定包含包含请求与响应两个方法 ...
- ASP.NET WEBAPI 的身份验证和授权
定义 身份验证(Authentication):确定用户是谁. 授权(Authorization):确定用户能做什么,不能做什么. 身份验证 WebApi 假定身份验证发生在宿主程序称中.对于 web ...
- 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi
一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...
- 让Asp.Net WebAPI支持OData查询,排序,过滤。
让Asp.Net WebAPI支持OData后,就能支持在url中直接输入排序,过滤条件了. 一.创建Asp.Net WebAPI项目: 二.使用NuGet安装Asp.Net WebAPI 2.2和O ...
- 返璞归真 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 新 ...
- 使用ASP.Net WebAPI构建REST服务(三)——返回值
Asp.Net WebAPI服务函数的返回值主要可以分为void.普通对象.HttpResponseMessag.IHttpActionResult e四种,本文这里简单的介绍一下它们的区别. 一.返 ...
- 前端angularjs+requirejs+dhtmlx 后端asp.net webapi
享一个前后端分离方案源码-前端angularjs+requirejs+dhtmlx 后端asp.net webapi 一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家 ...
- Asp.Net WebApi Swagger终极搭建
[PS:原文手打,转载说明出处,博客园] 关于为什么用Swagger 目前稍微有点规模的公司,已经从原先的瀑布流开发到了敏捷开发,实现前后端分离,为此后端工程师只关注写好Api即可,那程序员最讨厌的就 ...
随机推荐
- 使用 SyndicationFeed 输出 Rss
以前生成 RSS 都是使用拼接 Xml 的方式生成的,不仅麻烦而且还不规范. #region 输出指定分类编号的消息源内容... /// <summary> /// 输出指定分类编号的消息 ...
- FAILURE: Build failed with an exception.
FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:installD ...
- JRE和JDK
转自:http://www.cnblogs.com/myitm/archive/2011/05/03/2035942.html 很多程序员已经干了一段时间java了依然不明白jdk与jre的区别. ...
- 【PRML读书笔记-Chapter1-Introduction】1.6 Information Theory
熵 给定一个离散变量,我们观察它的每一个取值所包含的信息量的大小,因此,我们用来表示信息量的大小,概率分布为.当p(x)=1时,说明这个事件一定会发生,因此,它带给我的信息为0.(因为一定会发生,毫无 ...
- Safari下默认10位数字为电话号码,点击拨号
<meta content="telephone=no" name="format-detection"/>
- 爬虫技术 -- 基础学习(一)HTML规范化(附特殊字符编码表)
最近在做网页信息提取这方面的,由于没接触过这系列的知识点,所以逛博客,看文档~~看着finallyly大神的博文和文档,边看边学习边总结~~ 对网站页面进行信息提取,需要进行页面解析,解析的方法有以下 ...
- ruby -- 进阶学习(七)strong parameters之permitted.has_key
简单例子: params = ActionController::Parameters.new(user: { name: 'Francesco', age: 22, role: 'admin' }) ...
- get新技能: 如何设置元素高度与宽度成特定比例。宽度改变,高度自动按比例改变。 例如设置宽高比16:9。
设置宽高比在很多时候是有用的. 下面的栗子,我们设置一个容器的宽高比为16:9 //HTML代码片段 <div class="container"> <div c ...
- 二叉堆(二)之 C++的实现
概要 上一章介绍了堆和二叉堆的基本概念,并通过C语言实现了二叉堆.本章是二叉堆的C++实现. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的C++实现(完整源码)4. 二叉堆的C++测试程 ...
- debian系统root用户登录
Debian默认不允许root登录,所以修改之. 让Debian以root登录 1).首先修改gdm3的设定文件(/etc/gdm3/deamon.conf),在[security]字段后面追加如下一 ...