ASP.NET WebAPI 09 Controller的激活

时间:2022-12-14 09:40:07

在Controller之前我们先回顾一下HttpMessageHandler通道。

ASP.NET WebAPI 09 Controller的激活

在这个图中我留一个HttpContollerDispatcher没有说明。因为这个类也是继承自HttpMessageHandler,但由于HttpRoutingDispatcher已经不继承DelegatingHandler,所以就没有把HttpControllerDisPatcher作为HttpMessageHandler通道的最后一个节点。

HttpControllerDispather的主要功能就是根据请求路径筛选出Contoller,并激活运行。

HttpController

在程序中默认创建的Controller都继承自抽象类ApiController,但在WebAPI只要Controller实现接口IHttpController即可。

public interface IHttpController

{ 

Task<System.Net.Http.HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken); 

}

IHttpController只有一个ExecuteAsync方法,从方法的返回值。

HttpControllerDispatcher的SendAsync方法可以分成4个步骤:

  1. 获取HttpControllerDescriptor
  2. 创建HttpController
  3. 获取Controller上下文(HttpControllerContext)
  4. 执行HttpController的ExecuteAsync方法

获取HttpControllerDescriptor

HttpControllerDescriptor封装了某个HttpController的元数据(ControllerName,ControllerType)。ControllerType是HttpController对应的类型,因为有了这些信息,所以HttpControllerDescriptor就有了创建HttpController的能力

public class HttpControllerDescriptor

 { 

public HttpControllerDescriptor(); 

public HttpControllerDescriptor(HttpConfiguration configuration, string controllerName, Type controllerType); 

public HttpConfiguration Configuration { get; set; } 

public string ControllerName { get; set; } 

public Type ControllerType { get; set; } 

 }

整个获取HttpControllerDescriptor可以看成是根据路由变量controller的值在程序集中查找HttpControllerDescriptor。

WebAPI提供了查找的"标准化组件":HttpControllerSelector<IHttpControllerSelector,DefalutHttpControllerSelector>。

public interface IHttpControllerSelector

 { 

IDictionary<string, HttpControllerDescriptor> GetControllerMapping(); 

HttpControllerDescriptor SelectController(HttpRequestMessage request); 

 }

GetControllerMapping返回所有的HttpControllerDescriptor, SelectController按ControllerName返回ControllerType。

当然出于效率的考虑,WebAPI不会每次都去程序集中去查找。也是会做相应的缓存。对于加载缓存由两个"标准化组件"完成:IAssembliesResolver,IHttpControllerTypeResolver

IAssembliesResolver用于加载程序集。ASP.NET WebAPI注册是WebHostAssembliesResolver ,它定义在System.Web.Http.WebHost.dll中。它几乎返回运行过程中所有的程序集。

IHttpControllerTypeResolver用于从IAssembliesResolver获取到的程序集中筛选出所有的HttpController。WebAPI对它的默认实现是DefaultHttpControllerTypeResolver。筛选HttpController要满足如下条件:

  1. 直接或间接实现IHttpController的类
  2. 该类是公开的,非抽象的
  3. 该类的类名应该是以Controller结束

创建Controller

在得到HttpControllerDescriptor之后,HttpControllerDescriptor自身就有CreateController方法去创建Controller,但具体的工作HttpControllerDescriptor交给了HttpControllerActivator完成。

public interface IHttpControllerActivator

 { 

IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType); 

 }

HttpControllerActivator是作为"标准化组件"注册在ServicesContainer中的.WebAPI的默认实现是DefaultHttpControllerActivator。

在DefaultHttpControllerActivator中最优先使用的并不是反射,而是采用的DependencyResolver方式进行创建。只有当DependencyResolver返回空是才采用反射方式创建HttpController,上一篇我也提到过HttpConfiguration的DependencyResolver默认是EmptyResolver,所以实际上WebAPI默认采用反射的方式创建HttpController。

当然我们可以自己去实现DependencyResolver。在Demo中我用Unity自大做了一个简单的UnityDependencyResolver。

Controller上下文

Controller上下文对应的类的是HttpControllerContext,ApiController的ControllerContext就是HttpControllerContext对象。 ControllerContext包含了请求中的各种信息。激活Controller最后一步就是根据请求信息生成ControllerContext并赋值给ApiController.ControllerContext。

public class HttpControllerContext

 { 

public HttpControllerContext(); 

public HttpControllerContext(HttpConfiguration configuration, IHttpRouteData routeData, HttpRequestMessage request); 

public HttpControllerContext(HttpRequestContext requestContext, HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, IHttpController controller); 

public HttpConfiguration Configuration { get; set; } 

public IHttpController Controller { get; set; } 

public HttpControllerDescriptor ControllerDescriptor { get; set; } 

public HttpRequestMessage Request { get; set; } 

public HttpRequestContext RequestContext { get; set; } 

public IHttpRouteData RouteData { get; set; } 

 }

在ApiController中有一Initialize方法,该方法就是用于设置ControllerContext并标识ApiControlle已完成初始化(当ApiController未标识完成时会抛出InvalidOperationException异常)。所以我们在重写该方法时一定不要漏掉base.Initialize。

protected virtual void Initialize(HttpControllerContext controllerContext)

整个Contoller的激活大概如下流程:

ASP.NET WebAPI 09 Controller的激活

源码

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

ASP.NET WebAPI 09 Controller的激活的更多相关文章

  1. ASP&period;NET MVC Controller的激活

    最近抽空看了一下ASP.NET MVC的部分源码,顺带写篇文章做个笔记以便日后查看. 在UrlRoutingModule模块中,将请求处理程序映射到了MvcHandler中,因此,说起Controll ...

  2. Asp&period;net mvc 中的 Controller 的激活

    Controller 激活是指根据路由系统解析出来的 Controller 的名称创建 控制器(Controller)的过程,这里的控制器泛指实现了 IController 接口的类型 激活过程中的核 ...

  3. ASP&period;NET MVC——Controller的激活

    Controller的激活是根据在路由过程得到的Controller名称来创建对应的Controller对象.相关类如图: Controller激活的过程可通过如下序列图表示: 代码示例如下: str ...

  4. 重温ASP&period;NET WebAPI(二)进阶

    重温ASP.NET WebAPI(二)进阶   介绍 本文为个人对WebApi的回顾无参考价值. 本文内容: Rest和UnitOfWork 创建WebAPi的流程 IOC-Unity的使用 MEF ...

  5. Asp&period;Net WebApi核心对象解析(上篇)

    生活需要自己慢慢去体验和思考,对于知识也是如此.匆匆忙忙的生活,让人不知道自己一天到晚都在干些什么,似乎每天都在忙,但又好似不知道自己到底在忙些什么.不过也无所谓,只要我们知道最后想要什么就行.不管怎 ...

  6. ASP&period;NET WebApi 文档Swagger深度优化

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明博客园蜗牛原文地址,cnblogs.com/tdws   写在前面 请原谅我这个标题党,写到了第100篇随笔,说是深度优化,其实也并没有什么深度 ...

  7. ASP&period;NET WebApi 文档Swagger中度优化

    本文版权归博客园和作者吴双本人共同所有,转载和爬虫请注明原文地址:www.cnblogs.com/tdws   写在前面 在后台接口开发中,接口文档是必不可少的.在复杂的业务当中和多人对接的情况下,简 ...

  8. ASP&period;NET WEBAPI 的身份验证和授权

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

  9. Enable Cross-Origin Requests in Asp&period;Net WebApi 2&lbrack;Reprint&rsqb;

    Browser security prevents a web page from making AJAX requests to another domain. This restriction i ...

随机推荐

  1. Linux设置环境变量小结&colon;设置永久变量&amp&semi;临时变量 全局变量&amp&semi;局部变量

    1.总结背景 在linux系统下,如果你下载并安装了应用程序,很有可能在键入它的名称时出现“command not found”的提示内容.如果每次都到安装目标文件夹内,找到可执行文件来进行操作就太繁 ...

  2. python 练习 18

    #!/usr/bin/python # -*- coding: UTF-8 -*- import time print time.strftime('%Y-%m-%d %H:%M:%S',time.l ...

  3. centos6&period;4下安装freetds使php支持mssql

    centos版本:6.4 php版本5.3.17 没有安装之前的情况:nginx+php+mysql+FPM-FCGI 接下来安装步骤如下: 1.打开http://www.freetds.org/,进 ...

  4. C&plus;&plus;资源之不完全导引 &lpar;转载&rpar;

    C++资源之不完全导引(完整版)- - 这文章太强了,我一定要转载,否则对不起观众,对不起自己.(liigo) 发信人: NULLNULL (空空), 信区: VC标  题: C++资源之不完全导引( ...

  5. &lbrack;LeetCode&rsqb; 344 Reverse String &amp&semi;&amp&semi; 541 Reverse String II

    原题地址: 344 Reverse String: https://leetcode.com/problems/reverse-string/description/ 541 Reverse Stri ...

  6. 自守数算法----C语言实现

    #include <stdio.h> //自守数算法 //ep : 25 ^ 2 = 625 76 ^ 2 = 5776 9376 ^ 2 = 87909376 /*ep : * 376 ...

  7. Jmeter使用JDBC请求简介

    1.现在oracle或mysql的jdbc然后放到jmeter的lib路径下 2.添加jdbc默认请求控件. 3.添加jdbc请求 4.发送 5.出现ORA-00911错误是由于sql语句错误,注意别 ...

  8. C&num;设计模式&lpar;8&rpar;——桥接模式(Bridge Pattern)(转)

    一.引言 这里以电视遥控器的一个例子来引出桥接模式解决的问题,首先,我们每个牌子的电视机都有一个遥控器,此时我们能想到的一个设计是——把遥控器做为一个抽象类,抽象类中提供遥控器的所有实现,其他具体电视 ...

  9. APP打包提交审核的步骤

  10. Kubernetes总结

    1.Kubernetes简介 在了解Kubernetes之前,我们有必要先简单了解一下传统的运维模式.在传统的项目架构中(单体or微服务),我们一般将项目打包为war或fatJar的方式进行部署. 在 ...