亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

ASP.NET Web API 控制器執行過程(一)

2019-11-17 01:44:13
字體:
來源:轉載
供稿:網友

asp.net Web API 控制器執行過程(一)

ASP.NET Web API 控制器執行過程()

前言

前面兩篇講解了控制器的創建過程,只是從框架源碼的角度去簡單的了解,在控制器創建過后所執行的過程也是尤為重要的,本篇就來簡單的說明一下控制器在創建過后將會做哪些工作。

ASP.NET Web API 控制器執行過程

  • ASP.NET Web API 控制器執行過程(一)
  • ASP.NET Web API 控制器執行過程(二)

控制器執行過程

我們知道控制器的生成過程都是在HttpControllerDispatcher類型中來操作的,那我們要想知道控制器在創建過后執行操作的入口點也必須在HttpControllerDispatcher類型中才能發現。來看如下示例代碼:

代碼1-1

    PRivate Task<HttpResponseMessage> SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken)    {        IHttpRouteData routeData = request.GetRouteData();        HttpControllerDescriptor descriptor = this.ControllerSelector.SelectController(request);             IHttpController controller = descriptor.CreateController(request);            HttpConfiguration configuration = request.GetConfiguration();        HttpControllerContext controllerContext = new HttpControllerContext(descriptor.Configuration, routeData, request) {            Controller = controller,            ControllerDescriptor = descriptor        };        return controller.ExecuteAsync(controllerContext, cancellationToken);}

看過前面兩篇的朋友看到這里的代碼一定會很熟悉了,控制器的生成過程就包含在了其中,在代碼1-1中我們會看到HttpControllerContext類型,從它的名稱來看想必大家也都知道了它的作用,代表著進入控制器處理階段的邏輯上的上下文對象,并且封裝著一些很重要的信息。

HttpControllerContext控制器上下文

示例代碼1-2

    public class HttpControllerContext    {        public HttpControllerContext();        public HttpControllerContext(HttpConfiguration configuration, IHttpRouteData routeData, HttpRequestMessage request);        public HttpConfiguration Configuration { get; set; }        public IHttpController Controller { get; set; }        public HttpControllerDescriptor ControllerDescriptor { get; set; }        public HttpRequestMessage Request { get; set; }        public IHttpRouteData RouteData { get; set; }    }

結合代碼1-2和代碼1-1可以看到在HttpControllerContext類型中對HttpConfiguration類型的對象,它的重要性不用多說了,里面包含著很多配置信息以及存放基礎設施的容器對象,然后就是路由數據對象IHttpRouteData類型,以及最后的Http請求對象HttpRequestMessage類型的對象,并且在代碼1-1中對HttpControllerContext類型中的Controller和ControllerDescriptor屬性進行了賦值,Controller屬性對應的就是當前被創建好的控制器,而ControllerDescriptor屬性則是表示Controller屬性對應控制器的描述類型,現在回頭再看一下HttpControllerContext類型的對象就知道它里面包含的內容是有多重要了。

現在我們再回到代碼1-1中,最后我們看到是由IHttpController類型的變量controller調用方法ExecuteAsync()方法由此進入控制器中,一般控制器都是繼承自ApiController,我們就從ApiController類型來入手。

ApiController類型

示例代碼1-3

    public abstract class ApiController : IHttpController, IDisposable    {        public virtual Task<System.Net.Http.HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken);    }

在代碼1-3中我們可以看到再ApiController類型中定義了ExecuteAsync()方法,ApiController為抽象類型,控制器的主要執行過程也就是都在ExecuteAsync()方法中,下面我看一下具體的實現,如下示例代碼。

代碼1-4

    public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)    {        HttpControllerDescriptor controllerDescriptor = controllerContext.ControllerDescriptor;        ServicesContainer controllerServices = controllerDescriptor.Configuration.Services;        HttpActionDescriptor actionDescriptor = controllerServices.GetActionSelector().SelectAction(controllerContext);        HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor);        FilterGrouping grouping = new FilterGrouping(actionDescriptor.GetFilterPipeline());        IEnumerable<IActionFilter> actionFilters = grouping.ActionFilters;        IEnumerable<IAuthorizationFilter> authorizationFilters = grouping.AuthorizationFilters;        IEnumerable<IExceptionFilter> exceptionFilters = grouping.ExceptionFilters;        return InvokeActionWithExceptionFilters(InvokeActionWithAuthorizationFilters(actionContext, cancellationToken, authorizationFilters, () => actionDescriptor.ActionBinding.ExecuteBindingAsync(actionContext, cancellationToken).Then<HttpResponseMessage>(delegate {            this._modelState = actionContext.ModelState;            return InvokeActionWithActionFilters(actionContext, cancellationToken, actionFilters, () => controllerServices.GetActionInvoker().InvokeActionAsync(actionContext, cancellationToken))();        }, new CancellationToken(), false))(), actionContext, cancellationToken, exceptionFilters);   }

代碼1-4中定義了控制器的執行過程,我們就從源碼的角度去了解一下控制器的執行過程。

在代碼1-4中先是從控制器上下文對象中獲取當前控制器類型的描述對象HttpControllerDescriptor類型的實例,而后從HttpControllerDescriptor類型實例從獲取在HttpConfiguration中的服務容器ServicesContainer類型的實例,對于這些類型前面的篇幅或多或少的講過了。

在這之后從服務容器中獲取IHttpActionSelector類型的行為選擇器并且經過篩選獲取到最佳匹配的HttpActionDescriptor類型,在之前也有講到過HttpControllerDescriptor,這里的HttpActionDescriptor跟其相似,就是表示控制其行為(方法)的元數據信息。

下面我就來講解一下控制器行為選擇器的執行過程,也就是它篩選方法的幾個步驟。

首先我們要知道控制器行為選擇器的類型,從代碼1-4中可以看到是通過服務容器對象的擴展方法來獲取的,在前面的篇幅也都講過了,這里可以得知我們要查看的控制器行為選擇器的類型就是ApiControllerActionSelector類型。

ApiControllerActionSelector控制器行為選擇器

示例代碼1-5

    public class ApiControllerActionSelector : IHttpActionSelector    {        // Fields        private readonly object _cacheKey;        private ActionSelectorCacheItem _fastCache;        private const string ActionRouteKey = "action";        private const string ControllerRouteKey = "controller";        // Methods        public ApiControllerActionSelector();        public virtual ILookup<string, HttpActionDescriptor> GetActionMapping(HttpControllerDescriptor controllerDescriptor);        private ActionSelectorCacheItem GetInternalSelector(HttpControllerDescriptor controllerDescriptor);        public virtual HttpActionDescriptor SelectAction(HttpControllerContext controllerContext);        // Nested Types        private class ActionSelectorCacheItem        {        }        private class LookupAdapter : ILookup<string, HttpActionDescriptor>, IEnumerable<IGrouping<string, HttpActionDescriptor>>, IEnumerable        {        }   }

從代碼1-5中我們可以看到ApiControllerActionSelector類型中包含著兩個私有類,這兩個私有類后面會有講到起到的作用也很重要。

下面我們還是回到代碼1-4中的邏輯,從調用控制器行為選擇器中調用SelectAction()方法開始。

在ApiControllerActionSelector類型中調用SelectAction()時,實際是由SelectAction()方法調用GetInternalSelector()方法生成一個控制器方法的緩存對象,也就是ApiControllerActionSelector類型的私有類ActionSelectorCacheItem,而真正的篩選工作都是由它來執行的,所以下面才是介紹的重點。

控制器方法選擇器-篩選方法的步驟

1初始化篩選

在ActionSelectorCacheItem類型的初始化的時候, ActionSelectorCacheItem實例中會首先根據HttpControllerDescriptor對象獲取到控制器本身的類型,然后利用反射的技術根據條件獲取到當前控制器類型中的所有方法,最后保存為MethodInfo[]。而所謂的條件就是(BindingFlags.Public 、BindingFlags.Instance、方法所屬類型必須是ApiController類型的)。

我們看下ActionSelectorCacheItem類型中的字段信息,這些字段里存放的都是很重要的數據,后面會一一說明。

示例代碼1-6

        private readonly ReflectedHttpActionDescriptor[] _actionDescriptors;        private readonly ILookup<string, ReflectedHttpActionDescriptor> _actionNameMapping;        private readonly IDictionary<ReflectedHttpActionDescriptor, string[]> _actionParameterNames = new Dictionary<ReflectedHttpActionDescriptor, string[]>();        private readonly HttpMethod[] _cacheListVerbKinds = new HttpMethod[] { HttpMethod.Get, HttpMethod.Put, HttpMethod.Post };        private readonly ReflectedHttpActionDescriptor[][] _cacheListVerbs;        private readonly HttpControllerDescriptor _controllerDescriptor;

1.1基礎信息初始化- ReflectedHttpActionDescriptor[] _actionDescriptors

這個時候初始化工作并沒有做完,這時候會把MethodInfo[]數組中的每個MethodInfo實例封裝成ReflectedHttpActionDescriptor類型的對象,對于類型稍后再說。在封裝成ReflectedHttpActionDescriptor類型的對象后,也會將每個實例存至一個ReflectedHttpActionDescriptor類型的數組中。

1.2 基礎信息初始化- IDictionary<ReflectedHtt

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲深夜福利网站| 91精品国产九九九久久久亚洲| 久久久国产精品一区| 亚洲国产精品va在线| 岛国av在线不卡| 亚洲iv一区二区三区| 日韩欧中文字幕| 国内精品小视频在线观看| 91在线免费看网站| 日韩欧美国产视频| 国产精品pans私拍| 98精品国产自产在线观看| 久久亚洲电影天堂| 91国产美女在线观看| 一本一道久久a久久精品逆3p| 国产精品午夜一区二区欲梦| 国产精品视频最多的网站| 欧美日韩综合视频| 91精品国产自产91精品| 茄子视频成人在线| 96精品久久久久中文字幕| 国产自产女人91一区在线观看| 91精品国产91久久久| 欧美高清在线视频观看不卡| 精品视频在线播放| 亚洲最新视频在线| 国产一区二区三区欧美| 亚洲奶大毛多的老太婆| 亚洲级视频在线观看免费1级| 国产一区二区三区视频| 日韩精品中文字幕在线播放| 国产成人综合久久| 亚洲人成在线播放| 久久国产精品电影| 97热精品视频官网| 久久久久久高潮国产精品视| 亚洲一区亚洲二区亚洲三区| 国产在线视频91| 91精品视频在线播放| 欧美成人黄色小视频| 亚洲激情第一页| 亚洲国产精品电影在线观看| 尤物99国产成人精品视频| 日本欧美一级片| 日韩二区三区在线| 国产精品专区第二| 欧美午夜精品在线| 欧美日韩精品在线播放| 日韩欧美精品在线观看| 亚洲福利在线视频| 国产91精品久久久久久久| 欧美美最猛性xxxxxx| 在线视频亚洲欧美| 欧美一级免费视频| 国产精品视频中文字幕91| 久久精品小视频| 国产91网红主播在线观看| 欧美中文在线视频| 91精品国产综合久久久久久久久| 5566日本婷婷色中文字幕97| 国模私拍视频一区| 亚洲区一区二区| 久久精品美女视频网站| 久久精品99久久久香蕉| 亚洲一区二区三区久久| 久久久久北条麻妃免费看| 日韩欧美亚洲范冰冰与中字| 色偷偷88888欧美精品久久久| 日韩精品中文字幕有码专区| 亚洲视频电影图片偷拍一区| 8050国产精品久久久久久| 2020久久国产精品| 欧美另类老肥妇| 亚洲日本中文字幕免费在线不卡| 国产精品嫩草影院久久久| 国内自拍欧美激情| 色狠狠久久aa北条麻妃| 亚洲电影免费观看高清完整版| 午夜精品视频网站| 亚洲一区二区三区四区在线播放| 国产一区二区欧美日韩| 日韩在线视频线视频免费网站| 国产精品18久久久久久麻辣| 国产999在线观看| 亚洲午夜色婷婷在线| 国产精品嫩草影院久久久| 日韩电影免费在线观看中文字幕| 97在线免费观看视频| 欧美老女人性生活| 日韩美女写真福利在线观看| 国产美女久久精品香蕉69| 日本精品视频在线播放| 日韩欧美国产黄色| 成人免费福利视频| 久久精品夜夜夜夜夜久久| 91禁国产网站| 中文字幕精品www乱入免费视频| 2024亚洲男人天堂| 欧美精品成人在线| 欧美亚洲免费电影| 久久精品国产亚洲精品| 日韩免费av片在线观看| 97视频免费在线观看| www亚洲欧美| 欧美激情在线一区| 欧美色欧美亚洲高清在线视频| 欧美高清一级大片| 亚洲级视频在线观看免费1级| 亚洲视频在线观看| 91美女高潮出水| 午夜欧美不卡精品aaaaa| 狠狠色噜噜狠狠狠狠97| 国产精品成人免费电影| 91美女福利视频高清| 国产日韩一区在线| 久久91精品国产91久久久| 国产日韩中文在线| 欧美一区亚洲一区| 在线看欧美日韩| 欧美激情久久久| 国产精品吊钟奶在线| 亚洲电影免费观看高清| 日韩av在线天堂网| 国产精品丝袜一区二区三区| 麻豆国产精品va在线观看不卡| 在线观看久久久久久| 国模视频一区二区| 成人xxxx视频| 国产激情999| 亚洲福利小视频| 91av视频导航| 97av在线视频| 国产成人一区二区三区电影| 欧美老少配视频| 午夜精品久久久久久久99热浪潮| 色综合老司机第九色激情| 国外视频精品毛片| 久久中文字幕视频| 疯狂做受xxxx欧美肥白少妇| 日韩在线欧美在线国产在线| 日韩免费不卡av| 国产suv精品一区二区| 欧美午夜无遮挡| 亚洲女人天堂色在线7777| 日韩视频免费看| 国内免费精品永久在线视频| 国产精品第100页| 91久久在线视频| 亚洲欧美国产一本综合首页| 亚洲欧美一区二区三区久久| 日韩视频亚洲视频| 综合欧美国产视频二区| 久久91亚洲精品中文字幕奶水| 欧美黄色三级网站| 国产精品都在这里| 亚洲最大福利视频网站| 国产日韩精品入口| 亚洲精品电影在线观看| 夜夜躁日日躁狠狠久久88av| 精品性高朝久久久久久久| 成人在线国产精品| 国产成人中文字幕| 国产精品偷伦视频免费观看国产| 欧美一区二区三区艳史|