Web APi之过滤器执行过程原理解析【二】(十一)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介:

前言

上一节我们详细讲解了过滤器的创建过程以及粗略的介绍了五种过滤器,用此五种过滤器对实现对执行Action方法各个时期的拦截非常重要。这一节我们简单将讲述在Action方法上、控制器上、全局上以及授权上的自定义特性的执行过程。

APiController 

之前有讲到该APiController,也就稍微介绍了,这节我们来详细此Web API控制器的基类:

复制代码
 1 public abstract class ApiController : IHttpController, IDisposable
 2 {
 3     // Fields
 4     private HttpConfiguration _configuration;
 5     private HttpControllerContext _controllerContext;
 6     private bool _disposed;
 7     private ModelStateDictionary _modelState;
 8     private HttpRequestMessage _request;
 9     private UrlHelper _urlHelper;
10 
11     // Methods
12     protected ApiController();
13     public void Dispose();
14     protected virtual void Dispose(bool disposing);
15     public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken);
16     protected virtual void Initialize(HttpControllerContext controllerContext);
17     internal static Func<Task<HttpResponseMessage>> InvokeActionWithActionFilters(HttpActionContext actionContext, CancellationToken cancellationToken, IEnumerable<IActionFilter> filters, Func<Task<HttpResponseMessage>> innerAction);
18     internal static Func<Task<HttpResponseMessage>> InvokeActionWithAuthorizationFilters(HttpActionContext actionContext, CancellationToken cancellationToken, IEnumerable<IAuthorizationFilter> filters, Func<Task<HttpResponseMessage>> innerAction);
19     internal static Task<HttpResponseMessage> InvokeActionWithExceptionFilters(Task<HttpResponseMessage> actionTask, HttpActionContext actionContext, CancellationToken cancellationToken, IEnumerable<IExceptionFilter> filters);
20 
21     // Properties
22     public HttpConfiguration Configuration { get; set; }
23     public HttpControllerContext ControllerContext { get; set; }
24     public ModelStateDictionary ModelState { get; }
25     public HttpRequestMessage Request { get; set; }
26     public UrlHelper Url { get; set; }
27     public IPrincipal User { get; }
28 
29     // Nested Types
30     private class FilterGrouping
31     {
32         // Fields
33         private List<IActionFilter> _actionFilters;
34         private List<IAuthorizationFilter> _authorizationFilters;
35         private List<IExceptionFilter> _exceptionFilters;
36 
37         // Methods
38         public FilterGrouping(IEnumerable<FilterInfo> filters);
39         private static void Categorize<T>(IFilter filter, List<T> list) where T: class;
40 
41         // Properties
42         public IEnumerable<IActionFilter> ActionFilters { get; }
43         public IEnumerable<IAuthorizationFilter> AuthorizationFilters { get; }
44         public IEnumerable<IExceptionFilter> ExceptionFilters { get; }
45     }
46 }
复制代码

我们首先来看看此类中的一个私有类 FilterGrouping ,顾名思义是对过滤器分组,我们查看其构造函数看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
public  FilterGrouping(IEnumerable<FilterInfo> filters)
{
     this ._actionFilters =  new  List<IActionFilter>();
     this ._authorizationFilters =  new  List<IAuthorizationFilter>();
     this ._exceptionFilters =  new  List<IExceptionFilter>();
     foreach  (FilterInfo info  in  filters)
     {
         IFilter instance = info.Instance;
         Categorize<IActionFilter>(instance,  this ._actionFilters);
         Categorize<IAuthorizationFilter>(instance,  this ._authorizationFilters);
         Categorize<IExceptionFilter>(instance,  this ._exceptionFilters);
     }
}

我们仅仅只需 _actionFilters 为例,其余一样,我们再来看看 Categorize 方法:

复制代码
1 private static void Categorize<T>(IFilter filter, List<T> list) where T: class
2 {
3     T item = filter as T;
4     if (item != null)
5     {
6         list.Add(item);
7     }
8 }
复制代码

从这里我们可以得知:

当我们在HttpActionDescriptor初始化创建了封装了Filter对象的FilterInfo的集合列表,此时然后利用此类中的三个属性类型:IActionFilter、IAuthorizationFilter、以及IExceptionFilter进行过滤器分组得到对应过滤器集合列表

执行过程原理解析 

下面我们通过例子来看看之执行过程,我们自定义以下五个过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/// <summary>
    /// 全局的行为过滤器
    /// </summary>
    public  class  CustomConfigurationActionFilterAttribute : FilterAttribute, IActionFilter
    {
        public  Task<HttpResponseMessage> ExecuteActionFilterAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }
 
    /// <summary>
    /// 控制器级行为过滤器
    /// </summary>
    public  class  CustomControllerActionFilterAttribute : FilterAttribute, IActionFilter
    {
        public  Task<HttpResponseMessage> ExecuteActionFilterAsync(System.Web.Http.Controllers.HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }
 
    /// <summary>
    /// 控制器方法级行为过滤器
    /// </summary>
    public  class  CustomActionFilterAttribute : FilterAttribute, IActionFilter
    {
        public  Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }
 
    /// <summary>
    /// 控制器级授权访问过滤器
    /// </summary>
    public  class  CustomControllerAuthorizationFilterAttribute : FilterAttribute, IAuthorizationFilter
    {
        public  Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }
 
    /// <summary>
    /// 控制器方法级授权访问过滤器
    /// </summary>
    public  class  CustomControllerActionAuthorizationFilterAttribute : FilterAttribute, IAuthorizationFilter
    {
        public  Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, System.Threading.CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            Console.WriteLine( this .GetType().Name);
            return  continuation();
        }
    }

接下来就是实现过滤器,配置文件中配置全局过滤器

1
config.Filters.Add( new  CustomConfigurationActionFilterAttribute());

控制器及方法上过滤器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[CustomControllerAuthorizationFilter]
[CustomControllerActionFilter]
public  class  ProductController : ApiController
{
     [CustomActionFilter]
     [CustomControllerActionAuthorizationFilter]
     public  string  GetFilter()
     {
         var  sb =  new  StringBuilder();
 
         var  actionSelector =  this .Configuration.Services.GetActionSelector();
         var  actionDesciptor = actionSelector.SelectAction( this .ControllerContext);
         foreach  ( var  filterInfo  in  actionDesciptor.GetFilterPipeline())
         {
             sb.AppendLine( "【FilterName:"  + filterInfo.Instance.GetType().Name +  ",FilterScope:"  + filterInfo.Scope.ToString() +  "】" );
         }
         return  sb.ToString();
     }
}

最后来查看其结果:

看到这里是不是有点疑惑怎么按照Global->Controller->Action来进行排序,如果你看过前面文章就会知道这是过滤器管道按照FilterScope来生成的,实际上在服务器端生成的顺序为 CustomControllerAuthorizationFilterAttribute 、 CustomControllerActionAuthorizationFilterAttribute 、 CustomConfigurationActionFilterAttribute 、 CustomControllerActionFilterAttribute 以及 CustomActionFilterAttribute 由此我们得出结论:

授权过滤器不管任何的FilterScope都是优于行为过滤器,而在同一种类型的过滤器中是根据FilterScope来确定执行顺序的。 

总结 

有关更多深入的内容就不再探讨,本想多写一点,但是状态不佳加上更多内容比较复杂以免说不太明白云里雾里,想想还是算了,就这样了,下面还是给出其一张执行的详细示意图,来源【过滤器执行过程

  

接下来将通过实例详细讲解Web API中的认证(Authentication)以及授权(Authorization),敬请期待。。。。。。











本文转自Jeffcky博客园博客,原文链接:http://www.cnblogs.com/CreateMyself/p/4855419.html,如需转载请自行联系原作者

目录
相关文章
|
4天前
|
运维 负载均衡 安全
深度解析:Python Web前后端分离架构中WebSocket的选型与实现策略
深度解析:Python Web前后端分离架构中WebSocket的选型与实现策略
22 0
|
3天前
|
前端开发 JavaScript API
惊呆了!学会AJAX与Fetch API,你的Python Web项目瞬间高大上!
在Web开发领域,AJAX与Fetch API是提升交互体验的关键技术。AJAX(Asynchronous JavaScript and XML)作为异步通信的先驱,通过XMLHttpRequest对象实现了局部页面更新,提升了应用流畅度。Fetch API则以更现代、简洁的方式处理HTTP请求,基于Promises提供了丰富的功能。当与Python Web框架(如Django、Flask)结合时,这两者能显著增强应用的响应速度和用户体验,使项目更加高效、高大上。
16 2
|
5天前
|
前端开发 API 开发者
从零到精通,AJAX与Fetch API让你的Python Web前后端交互无所不能!
从零到精通,AJAX与Fetch API让你的Python Web前后端交互无所不能!
17 3
|
21天前
|
安全 API 开发者
Web 开发新风尚!Python RESTful API 设计与实现,让你的接口更懂开发者心!
在当前的Web开发中,Python因能构建高效简洁的RESTful API而备受青睐,大大提升了开发效率和用户体验。本文将介绍RESTful API的基本原则及其在Python中的实现方法。以Flask为例,演示了如何通过不同的HTTP方法(如GET、POST、PUT、DELETE)来创建、读取、更新和删除用户信息。此示例还包括了基本的路由设置及操作,为开发者提供了清晰的API交互指南。
80 6
|
20天前
|
存储 JSON API
实战派教程!Python Web开发中RESTful API的设计哲学与实现技巧,一网打尽!
在数字化时代,Web API成为连接前后端及构建复杂应用的关键。RESTful API因简洁直观而广受欢迎。本文通过实战案例,介绍Python Web开发中的RESTful API设计哲学与技巧,包括使用Flask框架构建一个图书管理系统的API,涵盖资源定义、请求响应设计及实现示例。通过准确使用HTTP状态码、版本控制、错误处理及文档化等技巧,帮助你深入理解RESTful API的设计与实现。希望本文能助力你的API设计之旅。
46 3
|
19天前
|
开发框架 JSON 缓存
震撼发布!Python Web开发框架下的RESTful API设计全攻略,让数据交互更自由!
在数字化浪潮推动下,RESTful API成为Web开发中不可或缺的部分。本文详细介绍了在Python环境下如何设计并实现高效、可扩展的RESTful API,涵盖框架选择、资源定义、HTTP方法应用及响应格式设计等内容,并提供了基于Flask的示例代码。此外,还讨论了版本控制、文档化、安全性和性能优化等最佳实践,帮助开发者实现更流畅的数据交互体验。
42 1
|
21天前
|
JSON API 开发者
惊!Python Web开发新纪元,RESTful API设计竟能如此性感撩人?
在这个Python Web开发的新纪元里,RESTful API的设计已经超越了简单的技术实现,成为了一种追求极致用户体验和开发者友好的艺术表达。通过优雅的URL设计、合理的HTTP状态码使用、清晰的错误处理、灵活的版本控制以及严格的安全性措施,我们能够让RESTful API变得更加“性感撩人”,为Web应用注入新的活力与魅力。
40 3
|
2天前
|
JSON JavaScript API
商品详情数据接口解析返回的JSON数据(API接口整套流程)
商品详情数据接口解析返回的JSON数据是API接口使用中的一个重要环节,它涉及从发送请求到接收并处理响应的整个流程。以下是一个完整的API接口使用流程,包括如何解析返回的JSON数据:
|
3天前
|
前端开发 API 数据格式
颠覆传统!AJAX、Fetch API与Python后端,开启Web开发新篇章!
在Web开发领域,技术的快速迭代推动着应用不断进化。传统前后端交互方式已无法满足现代Web应用对高效、实时性和用户体验的需求。AJAX作为异步通信的先驱,使页面无需刷新即可更新部分内容,显著提升用户体验;尽管XML曾是其主要数据格式,但如今JSON已成为主流。Fetch API则以其简洁、灵活的特点成为AJAX的现代替代品,基于Promises的异步请求让开发更加高效。与此同时,Python后端凭借高效稳定和丰富的库支持,成为众多开发者的首选,无论是轻量级的Flask还是全功能的Django,都能为Web应用提供强大的支撑。
12 0
|
4天前
|
XML 前端开发 API
惊艳全场的秘诀!AJAX、Fetch API与Python后端,打造令人惊叹的Web应用!
惊艳全场的秘诀!AJAX、Fetch API与Python后端,打造令人惊叹的Web应用!
13 0

推荐镜像

更多