这是我看过WebApi实现代码后的一些总结,一方面加深自己的记忆,另外也希望能够帮助大家更深入的了解WebApi。

注:暂时没有好好的整理,可能有些晦涩难懂。

Webapi 控制器类必须实现IHttpController接口

首先调用HttpControllerRouteHandler通过请求上下文(RequestContext )创建创建HttpControllerHandler对象,用于处理请求

HttpControllerRouteHandler.GetHttpHandler(RequestContext requestContext) 获取 HttpControllerHandler

■、(IHttpHandler)HttpControllerHandler.ProcessRequest(HttpContext context)  创建IhttpHandler
→ 调用HttpServer.SendAsync(HttpRequestMessage request) (此类在GlobalConfiguration.DefaultServer中配置)
→ 把响应结果(HttpResponseMessage)写入Response.OutputStream输出流中输入到浏览器

■、下面看一下 HttpServer.SendAsync(HttpRequestMessage request)做的事情
→ 调用路由调度者 HttpRoutingDispatcher(路由调度者).SendAsync(HttpRequestMessage request) 根据请求的URL匹配路由表,并保存在请求消息中(HttpRequestMessage)
→ 继而调用HttpControllerDispatcher.SendAsync 请求继续向下走

■、调用 HttpControllerDispatcher(控制器调度者).SendAsync(HttpRequestMessage request)

→ 调用 IHttpControllerSelector.SelectController(HttpRequestMessage request) 此方法构建控制器描述类,IHttpControllerSelector通过HttpConfiguration.Services注入

→ HttpControllerDescriptor.CreateController(request) 创建控制器对象

→ CreateControllerContext(HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor,
IHttpController controller)创建控制器上下文对象(HttpControllerContext)

→ 调用(IHttpController) ApiController.ExecuteAsync()  执行控制器核心方法

■、(IHttpControllerSelector)DefaultHttpControllerSelector.SelectController(HttpRequestMessage request)  看一下默认控制器描述(HttpControllerDescriptor)实现类

→ 从请求信息中获取路由数据IHttpRouteData

→ 从路由中创建HttpControllerDescriptor对象,用于描述控制器(名称、类型、过滤器、特性等)
创建HttpActionDescriptor对象(名称、返回类型、过滤器、特性、输入参数等)

→ 通过DefaultHttpControllerActivator 创建实现 IHttpController 接口的实例

■、(IHttpController)ApiController.ExecuteAsync()
→ 从HttpConfiguration.Services获取IHttpActionSelector实现类(ApiControllerActionSelector)
(IHttpActionSelector)ApiControllerActionSelector.SelectAction()
1、根据控制器类型获得所有Action方法
2、创建HttpActionDescriptor的实现类ReflectedHttpActionDescriptor
3、获得 ActionBinding 实现类 FormatterParameterBinding

→ ActionFilterResult.ExecuteAsync(ActionBinding binding, HttpActionContext context, IHttpActionSelector Selector) 执行Action

→ ApiControllerActionInvoker.InvokeActionAsync()

→ ReflectedHttpActionDescriptor.ExecuteAsync()

→ ActionExecutor.GetExecutor() 返回响应结果HttpResponseMessage实例

■、ActionFilterResult.ExecuteAsync(ActionBinding binding, HttpActionContext context, IHttpActionSelector Selector)
→ 调用 binding.ExecuteBindingAsync() 把参数值放入 HttpActionContext.ActionArguments 字典中
→ 从服务管理器中(Services)获取 IHttpActioninvoker 实现类ApiControllerActionInvoker 对象,调用ApiControllerActionInvoker.InvokeActionAsync
→ ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary<string, object> arguments)

WebApi里大部分对象通过 ServicesContainer 管理,通过HttpConfiguration.Services可以获得此对象,并且可以通过services.Replace方法替换接口的实现类,如:
HttpConfiguration.Services.Replace(typeof(IHttpControllerActivator), new CoreApiControllerActivator(IocManager));

API参数构建:
■、调用IHttpActionResult.ExecuteAsync()时构建参数
1、从HttpActionDescriptor中获取ActionBinding传入 IHttpActionResult实例构造函数中
▲、HttpActionBinding实例的创建
1、从服务管理器(services)中获取IActionValueBinder实现类(DefaultActionValueBinder)实例
2、调用(IActionValueBinder)DefaultActionValueBinder.GetBinding(HttpActionDescriptor)
△、从HttpActionDescriptor中获得参数数组HttpParameterDescriptor[]
△、获取HttpParameterBinding对象:先获取参数的ParameterBindingAttribute属性(如:FromBodyAttribute),
调用GetBinding方法,从HttpConfiguration中获取参数格式化工具的集合IEnumerable<MediaTypeFormatter>
(如:JsonMediaTypeFormatter、XmlMediaTypeFormatter等等)
△、从服务管理器中获取IBodyModelValidator对象
△、返回(HttpParameterBinding)FormatterParameterBinding 对象
3、创建HttpActionBinding实例,传入(HttpParameterBinding)FormatterParameterBinding对象集合,返回HttpActionBinding
2、调用HttpActionBinding.ExecuteBindingAsync()
▲、循环调用之前传入的FormatterParameterBinding.ExecuteBindingAsync
1、从HttpActionContext.HttpControllerContext.HttpRequestMessage中获取HttpRequestMessage
2、从请求消息Request.Content中获取HttpContent
3、根据请求报文头Content-Type获取对应MediaTypeFormatter(如:JsonMediaTypeFormatter、XmlMediaTypeFormatter等等)用于处理参数对象
4、调用(MediaTypeFormatter)JsonMediaTypeFormatter.ReadFromStreamAsync 返回参数对象
3、将参数设置到HttpActionContext.ActionArguments字典中
4、参数构建完毕

笔者心血,所以请尊重原创:http://www.cnblogs.com/Newd/p/7607431.html

WebApi实现原理解析笔记的更多相关文章

  1. 结合之前看的一些东西,阅读RockMQ实战与原理解析笔记

    Topic有多个message queue,消息可以并行的向各个message queue发送,消费者也可以并行的从多个message queue读取消息并消费 clustering模式消费一个top ...

  2. ABP中动态WebAPI原理解析

    ABP中动态WebAPI原理解析 动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类 ...

  3. Skinned Mesh原理解析和一个最简单的实现示例

    Skinned Mesh 原理解析和一个最简单的实现示例   作者:n5 Email: happyfirecn##yahoo.com.cn Blog: http://blog.csdn.net/n5 ...

  4. 基于OpenCV进行图像拼接原理解析和编码实现(提纲 代码和具体内容在课件中)

    一.背景 1.1概念定义 我们这里想要实现的图像拼接,既不是如题图1和2这样的"图片艺术拼接",也不是如图3这样的"显示拼接",而是实现类似"BaiD ...

  5. Spring IOC设计原理解析:本文乃学习整理参考而来

    Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...

  6. APPcrawler基础原理解析及使用

    一.背景 一年前,我们一直在用monkey进行Android 的稳定性测试 ,主要目的就是为了测试app 是否会产生Crash,是否会有ANR,页面错误等问题,在monkey测试过程中,实现了脱离Ca ...

  7. java线程池原理解析

    五一假期大雄看了一本<java并发编程艺术>,了解了线程池的基本工作流程,竟然发现线程池工作原理和互联网公司运作模式十分相似. 线程池处理流程 原理解析 互联网公司与线程池的关系 这里用一 ...

  8. 深入探索Android热修复技术原理读书笔记 —— 代码热修复技术

    在前一篇文章 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍中,对热修复技术进行了介绍,下面将详细介绍其中的代码修复技术. 1 底层热替换原理 在各种 Android 热修复方案中 ...

  9. 深入探索Android热修复技术原理读书笔记 —— 资源热修复技术

    该系列文章: 深入探索Android热修复技术原理读书笔记 -- 热修复技术介绍 深入探索Android热修复技术原理读书笔记 -- 代码热修复技术 1 普遍的实现方式 Android资源的热修复,就 ...

随机推荐

  1. SoapUI进行接口测试,怎么应对接口地址总是变化!

    如果是没有代码能力的小白,要利用工具进行接口测试的时候,经常会遇到接口地址或者接口参数变化的问题,然后不得不在他们改了接口之后,就手动去改所有的请求链接地址和接口参数!1-5个请求,我们手动改还应付的 ...

  2. Html5笔记之小结

    随着Android,IOS手机,平板等各种App的不断扩增,加上对过去传统HTML的的各种不完善,例如视频依靠Flash,对手机和桌面的不兼容等等.HTML5来了,来解决这些问题了. Html5是W3 ...

  3. [2012-08-06]awk多文件合并并按文件名分段

    以下代码满足这样的需求: 多个文件内容合并到一个文件A中(如果没有下面这条,使用cat就能解决) 文件A中每段内容之前保留原先的文件名 awk 'tmp!=FILENAME{tmp=FILENAME; ...

  4. jmeter系列-------脚本调试

    1.调试的时候 可以只跑需要调试的接口,禁用其他的接口 2.每个接口都需要增加断言眼,保证脚本的结果的正确性 3.验证脚本的可靠性,可以切换用户(测试变量)来进行调试 4.使用Debug Sample ...

  5. Selenium 定位网页元素

    第一 定位元素辅助工具 IE中在元素上右击 ->  “检查元素”,或按F12键打开开发者工具: Chrome中在元素上右击 -> “审查元素”,或按F12键打开开发者工具: Firefox ...

  6. SpirngMVC入门第一天

                                         SpringMVC第一天 1.   计划 第一天 1.SpringMVC介绍 2.入门程序 3.SpringMVC架构讲解 a ...

  7. poj 1200字符串hash

    题意:给出不同字符个数和子串长度,判断有多少个不同的子串 思路:字符串hash. 用字符串函数+map为什么会超时呢?? 代码: #include <iostream> #include ...

  8. JavaScript学习日志(一):变量,作用域和内存问题

    一,变量分为两种类型:基本类型值和引用类型值,基本类型包括:Undefined, String, Boolean, Null, Number,我们无法给基本类型值添加属性: 二,复制变量值的时候,如果 ...

  9. 第二周C++学习总结

    经过这个星期的学习,认识C语言C++语言,学会打代码,但是打出第一个代码还是经历了很大困难,首先我对于打代码真的一窍不通,其次我连打代码的软件也不会装,但在班导的帮助下我还是装好了软件,在打第一个代码 ...

  10. MPLS LDP随堂笔记1

    LDP 的使用原因(对于不同协议来说) LDP的四大功能 发现邻居 hello 5s 15s 224.0.0.2 发现邻居关系 R1 UDP 646端口 R2 UDP 646端口 此时形成邻居 建立邻 ...