zoukankan      html  css  js  c++  java
  • WebApi实现原理解析笔记

    这是我看过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)  看一下默认控制器选择器(IHttpControllerSelector)实现类

    → 从请求信息中获取路由数据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

    Newd

    版权声明

    作者:扶我起来我还要敲

    地址:https://www.cnblogs.com/Newd/p/7607431.html

    © Newd 尊重知识产权,引用请注出处

    广告位

    (虚位以待,如有需要请私信)

  • 相关阅读:
    poco之查看布局树
    airtest连接真机
    airtest之ADB调用
    airtest连接无线连接设备
    airtest之模拟器连接
    airtest之api、图片处理
    airtest介绍
    fidder保存请求和保存响应结果
    7 js之 条件语句
    IE6/IE7之浮动元素最后一个字母重复Bug
  • 原文地址:https://www.cnblogs.com/Newd/p/7607431.html
Copyright © 2011-2022 走看看