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

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

ASP.NET Web API中的Controller

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

asp.net Web API中的Controller

雖然通過Visual Studio向導在ASP.NET Web API項目中創建的 Controller類型默認派生與抽象類型ApiController,但是ASP.NET Web API框架本身只要求它實現IHttpController接口即可,所以我們將其統稱為HttpController。既然HttpController指的是所有實現了IHttpController接口的類型,我們自然得先來了解一下這個接口的定義。如下面的代碼片斷所示,在IHttpController接口中僅僅定義了唯一的方法ExecuteAsync方法,它以異步的方式執行HttpController,并返回一個Task<HttPResponseMessage>對象。[本文已經同步到《How ASP.NET Web API Works?》]

   1: public interface IHttpController
   2: {
   3:     Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken);
   4: }

HttpController可以視為對ASP.NET Web API的消息處理管道的延續。通過“ASP.NET Web API標準的“管道式”設計”的介紹我們知道位于管道末端的是一個HttpRoutingDispatcher對象。當SendAsync方法被執行的時候,HttpRoutingDispatcher會利用隸屬于它的HttpControllerDispatcher來激活目標HttpController對象,隨后調用該對象的ExecuteAsync方法并將返回的Task<HttpResponseMessage>對象作為返回值。右圖揭示了包含激活的HttpController在內的消息處理管道的結構。

一、HttpControllerContext

與HttpMessageHandler的SendAsync方法有所不同,HttpController的ExecuteAsync方法并沒有一個表示請求的類型為HttpRequestMessage的參數,取而代之的是一個HttpControllerContext類型的參數。HttpControllerContext定義在命名空間“System.Web.Http.Controllers”下,表示執行HttpController的上下文。

如下面的代碼片斷所示,通過定義在HttpControllerContext中的屬性我們可以得到用于配置消息處理管道的HttpConfiguration對象和封裝路由數據的HttpRouteData對象,以及表示當前請求的HttpRequestMessage對象。這三個屬性可以在構建HttpControllerContext的時候直接通過構造函數的參數指定,我們也可以先創建一個空的HttpControllerContext對象之后直接對這些屬性賦值。

   1: public class HttpControllerContext
   2: {
   3:     public HttpControllerContext();
   4:     public HttpControllerContext(HttpConfiguration configuration, IHttpRouteData routeData, HttpRequestMessage request);   
   5:     
   6:     public HttpConfiguration         Configuration { get; set; }
   7:     public IHttpRouteData            RouteData { get; set; }
   8:     public HttpRequestMessage        Request { get; set; }
   9:  
  10:     public IHttpController              Controller { get; set; }
  11:     public HttpControllerDescriptor     ControllerDescriptor { get; set; }
  12: }

一個HttpControllerContext對象表示執行HttpController的上下文,我們可以通過Controller屬性來獲取或者設置這個HttpController對象。除此之外,我們還可以利用另一個屬性ControllerDescriptor獲取或者設置用于描述HttpController的HttpControllerDescriptor對象(類型HttpControllerDescriptor定義在命名空間“System.Web.Http.Controllers”下)。

二、HttpControllerDescriptor

HttpControllerDescriptor封裝了某個HttpController類型的元數據,我們可以將它視為某個HttpController類型的描述對象。HttpControllerDescriptor具有根據元數據創建對應HttpController的能力,實際上ASP.NET Web API的HttpController激活系統就是根據HttpControllerDescriptor來創建目標HttpController的。

如下面的代碼片斷所示,我們可以通過HttpControllerDescriptor的屬性Configuration、ControllerName和ControllerType獲取當前的HttpConfiguration對象和被描述HttpController的名稱和類型。這三個屬性可以在構建HttpControllerDescriptor時通過構造函數的參數顯式指定,也可以先構建一個空的HttpControllerDescriptor對象,然后手工設置這些屬性。

   1: public class HttpControllerDescriptor
   2: {   
   3:     public HttpControllerDescriptor();
   4:     public HttpControllerDescriptor(HttpConfiguration configuration, string controllerName, Type controllerType);
   5:  
   6:     public virtual IHttpController CreateController(HttpRequestMessage request);
   7:  
   8:     public virtual Collection<T> GetCustomAttributes<T>() where T: class;
   9:     public virtual Collection<T> GetCustomAttributes<T>(bool inherit) where T: class;
  10:     public virtual Collection<IFilter> GetFilters();
  11:    
  12:     public HttpConfiguration     Configuration { get; set; }
  13:     public string                ControllerName { get; set; }
  14:     public Type                  ControllerType { get; set; }
  15:  
  16:     public virtual ConcurrentDictionary<object, object> Properties { get; }
  17: }

HttpControllerDescriptor具有創建HttpController的能力主要體現在其CreateController方法上,該方法完成了目標方法的激活。換句話說,目標HttpController的激活是通過調用描述它的HttpControllerDescriptor對象的CreateController方法完成的。本章的核心就在于剖析此方法的實現邏輯。

我們可以通過HttpControllerDescriptor的GetCustomAttributes<T>方法得到應用在被描述HttpController類型上指定類型的特性列表。調用另一個方法GetFilters可以獲取應用到目標HttpController類型上的所有Filter,Filter在ASP.NET Web API中是一個非常重要的概念,同時也是一種常見的擴展方式,我們會在本書第12章“過濾器”中對Filter進行單獨介紹。

HttpControllerDescriptor還具有一個字典類型的只讀屬性Properties,它使我們可以將任何一個對象附加到某個HttpControllerDescriptor上。我們在HttpRequestMessage和HttpConfiguration類型中已經看到過了類似的設計。

三、ApiController

我們現在來介紹一下我們創建HttpController類型默認繼承的基類ApiController。如下面的代碼片斷所示,除了實現接口IHttpController外,HttpController還采用標準的方式實現了另一個接口IDisposable。如果自定義HttpController需要實現一些資源回收的工作,可以將它們定義在重寫的(受保護的)虛方法Dispose中。

   1: public abstract class ApiController : IHttpController, IDisposable
   2: {
   3:     public virtual Task<HttpResponseMessage> ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken);
   4:     protected virtual void Initialize(HttpControllerContext controllerContext);
   5:     
   6:     public void Dispose();
   7:     protected virtual void Dispose(bool disposing);
   8:   
   9:     public HttpControllerContext     ControllerContext { get; set; }
  10:     public HttpConfiguration         Configuration { get; set; }
  11:     public HttpRequestMessage        Request { get; set; }
  12:     public IHttpRouteData            RouteData { get; set; }
  13:  
  14:     public ModelStateDictionary     ModelState { get; }
  15:     public UrlHelper                Url { get; set; }
  16:     public IPrincipal               User { get; }
  17: }

ApiController的三個屬性Configuration、Request和RouteData與此HttpControllerContext對象的同名屬性具有相同的引用。表示執行當前ApiController上下文的HttpControllerContext對象可以通過ControllerContext屬性獲取,這是一個可讀寫的屬性,意味著我們也可以通過設置該屬性為其指定相應的上下文。如果我們沒有對ControllerContext屬性進行顯式設置,該屬性會在第一次被獲取時被自動賦值。

ApiController的只讀屬性ModelState返回一個具有字典數據結構的ModelStateDictionary對象,包含其中的數據會被以“Model綁定”的形式綁定到目標Action方法的對應的參數。除此之外,此ModelStateDictionary還用于保存參數驗證失敗后的錯誤消息。另一個參數Url返回一個類型為UrlHelper的對象(UrlHelper定義在命名空間“System.Web.Http.Routing”下),我們利用它可以根據注冊的HttpRoute和提供的路由變量生成一個完整的URL。

ApiController的User屬性返回當前線程的Principal。相信讀者還會記得在本書第3章“消息處理管道”中介紹HttpServer時我們談到:如果當前線程的Principal為Null,作為消息處理管道“龍頭”的HttpServer會在SendAsync方法執行過程中創建一個空的GenericPrincipal對象作為當前線程的“匿名”Principal。所以對于匿名請求來說,這個User屬性會返回這個通過HttpServer設置的空GenericPrincipal對象。

從上面給出的代碼片斷我們還會看到ApiController包含一個受保護的Initialize方法,它會根據由指定HttpControllerContext提供的上下文信息對自身作相應的初始化。一旦Initialize方法被成功執行,當前ApiController對象將處于初始化狀態。此Initialize在默認情況下會在實現的ExecuteAsync方法中被自動調用。在默認情況下,ASP.NET Web API的HttpController激活系統總是創建一個新的HttpController來處理每一個請求。對于其類型繼承自ApiController的HttpController來說,如果在執行ExecuteAsync方法的時候發現當前的ApiController已經處于“初始化”的狀態,系統會直接拋出一個InvalidOperationException異常。

舉個簡單的例子,假設我們定義了如下一個繼承自ApiController的DemoController類型,并通如下的方式將原本為受保護的Initialize方法轉換成一個公有方法,以方便我們后續的調用。

   1: public class DemoController : ApiController
   2: {
   3:     public new void Initialize(HttpControllerContext controllerContext)
   4:     {
   5:         base.Initialize(controllerContext);
   6:     }
   7: }

然后我們執行如下一段代碼,它的特別之處在于在調用DemoController對象的ExecuteAsync方法之前調用了Initialize方法對其作了初始化處理。

   1: DemoController controller = new DemoController ();
   2: HttpControllerContext controllerContext = new HttpControllerContext(new HttpConfiguration(), new HttpRouteData(new HttpRoute()), new HttpRequestMessage());
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品国产精品自拍| 久久99精品久久久久久琪琪| 欧美性猛交xxxx偷拍洗澡| 97av在线影院| 亚洲三级 欧美三级| 成人黄色在线播放| 日韩欧美在线观看视频| 色一情一乱一区二区| 午夜精品福利在线观看| 国产激情999| 欧美精品成人91久久久久久久| 78m国产成人精品视频| 国产精品丝袜一区二区三区| 欧美性猛交xxxx黑人猛交| 久久亚洲精品小早川怜子66| 日韩一区二区av| 欧美极品欧美精品欧美视频| 国产精品极品美女粉嫩高清在线| 亚洲成人1234| 国产欧美精品日韩| 91在线视频一区| 日本亚洲欧美成人| 欧美午夜无遮挡| 久久久久亚洲精品| 精品久久久香蕉免费精品视频| 狠狠爱在线视频一区| 国内精品久久久久久| 日韩不卡中文字幕| 国产丝袜一区二区三区| 欧美国产精品人人做人人爱| 日本成人激情视频| 国产福利视频一区二区| 91欧美激情另类亚洲| 综合网日日天干夜夜久久| 91九色国产视频| 欧美性猛交xxxx富婆| 精品亚洲va在线va天堂资源站| 欧美最猛性xxxxx(亚洲精品)| 亚洲影影院av| 久久久久女教师免费一区| 亚洲自拍中文字幕| 久久久久在线观看| 国产午夜一区二区| 欧美成人午夜剧场免费观看| 亚洲欧美国产va在线影院| 欧美超级乱淫片喷水| 亚洲福利精品在线| 夜夜嗨av一区二区三区四区| 国产精品老女人精品视频| 亚洲区在线播放| 精品夜色国产国偷在线| 亚洲精品91美女久久久久久久| 日韩三级影视基地| 欧美精品videos另类日本| 欧美成人午夜视频| 日韩在线精品一区| 久久久亚洲成人| 国产精品久久久久久久av电影| 欧美在线视频观看免费网站| 97人洗澡人人免费公开视频碰碰碰| 亚洲午夜av电影| 国产精品99久久久久久www| 97视频在线观看免费高清完整版在线观看| 国产精品久久久久久亚洲影视| 福利一区福利二区微拍刺激| 亚洲午夜未满十八勿入免费观看全集| 亚洲人成在线观| 欧美性xxxx极品hd满灌| 欧美最猛性xxxxx免费| 97在线精品国自产拍中文| 久久国产精品久久国产精品| 欧美激情视频三区| 成人欧美一区二区三区在线湿哒哒| 97人洗澡人人免费公开视频碰碰碰| 日日摸夜夜添一区| 欧美成人中文字幕在线| 黄网动漫久久久| 亚洲激情视频在线观看| 欧美精品videossex性护士| 国产精品久久久久久久9999| 在线亚洲午夜片av大片| 中文欧美在线视频| 久久av中文字幕| 日韩欧美中文第一页| 亚洲男女自偷自拍图片另类| 午夜精品理论片| 97免费中文视频在线观看| 丰满岳妇乱一区二区三区| 亚洲综合精品一区二区| 国产亚洲欧洲高清一区| 国产精品爽爽ⅴa在线观看| 国产精品男人的天堂| 欧美午夜精品伦理| 欧美在线观看视频| 欧美精品一区在线播放| 8090理伦午夜在线电影| 日韩欧美在线视频日韩欧美在线视频| 在线亚洲欧美视频| 日韩av一卡二卡| 亚洲天堂av在线免费观看| 91精品国产91久久久久久不卡| 中文字幕在线国产精品| 欧洲亚洲免费视频| 日韩欧美在线免费| 成人看片人aa| 国产丝袜一区二区| 欧美在线视频免费播放| 一本色道久久综合亚洲精品小说| 精品国产一区二区三区四区在线观看| 国产一区二区丝袜高跟鞋图片| 色噜噜久久综合伊人一本| 亚洲性线免费观看视频成熟| 国产精品国内视频| 国产日韩在线一区| 成人免费视频网址| 精品国偷自产在线视频99| 欧美成人中文字幕| 欧美性猛交xxxx乱大交极品| 亚洲精品ady| 久久91亚洲人成电影网站| 九九热这里只有在线精品视| 91久久精品美女高潮| 亚洲精品免费在线视频| 久久中文字幕在线| 亚洲天堂网站在线观看视频| 欧美亚洲免费电影| 国产精品精品久久久| 欧美中在线观看| 97人人爽人人喊人人模波多| 97视频com| 日韩视频在线免费| 国产在线视频不卡| 疯狂做受xxxx欧美肥白少妇| 2019亚洲男人天堂| 国产成人精品久久二区二区91| 国产在线视频欧美| 国产精品美女免费看| 国产+成+人+亚洲欧洲| 亚洲美女中文字幕| 国产精品一区二区女厕厕| 欧美在线不卡区| 日韩电影在线观看永久视频免费网站| 欧美电影免费看| 欧美日韩中文字幕日韩欧美| 欧美黑人视频一区| 久久久999国产精品| 欧美激情xxxx| 亚洲美女喷白浆| 深夜福利国产精品| 国产精品网址在线| 91久久久久久久一区二区| 欧美精品videosex牲欧美| 欧美日韩国产成人在线观看| 国产精品成人一区二区三区吃奶| 国产精品久久网| 亚洲国产精品悠悠久久琪琪| 国产精品国产三级国产aⅴ浪潮| 精品久久久一区| 91a在线视频| 日韩欧美aaa| 日韩视频永久免费观看| 中文字幕av一区| 欧美成年人视频| 久久精品亚洲一区|