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.rzrgm.cn/Newd/p/7607431.html
版權聲明
作者:扶我起來我還要敲
地址:http://www.rzrgm.cn/Newd/p/7607431.html
? Newd 尊重知識產權,引用請注出處
廣告位
(虛位以待,如有需要請私信)
浙公網安備 33010602011771號