国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

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

ASP.NET Web API 管道模型

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

asp.net Web API 管道模型

ASP.NET Web API 管道模型

前言

ASP.NET Web API是一個獨立的框架,也有著自己的一套消息處理管道,不管是在WebHost宿主環境還是在SelfHost宿主環境請求和響應都是從消息管道經過的,這是必經之地,本篇就為大家簡單的介紹一下ASP.NET Web API框架中的管道對象模型。

ASP.NET Web API路由、管道

  • ASP.NET Web API 開篇介紹示例
  • ASP.NET Web API 路由對象介紹
  • ASP.NET Web API 管道模型
  • ASP.NET Web API selfhost宿主環境中管道、路由
  • ASP.NET Web API webhost宿主環境中管道、路由

管道模型介紹

HttpMessageHandler消息處理程序(基類)

    public abstract class HttpMessageHandler : IDisposable    {        PRotected HttpMessageHandler();        public void Dispose();        protected virtual void Dispose(bool disposing);        protected internal abstract Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);    }

上面的代碼中定義的是消息處理程序基類,在管道中的每一個消息處理部分都是繼承自它。

并且定義了一個會執行異步操作的SendAsync()方法,這個方法也是串聯管道中各個消息處理程序的一個入口,但是并不是靠它來串聯。

DelegatingHandler消息處理程序(基類)

    public abstract class DelegatingHandler : HttpMessageHandler    {        protected DelegatingHandler();        protected DelegatingHandler(HttpMessageHandler innerHandler);        public HttpMessageHandler InnerHandler { get; set; }        protected override void Dispose(bool disposing);        protected internal override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);    }

這里的DelegatingHandler繼承自HttpMessageHandler類型,而且DelegatingHandler也是抽象類型,DelegatingHandler類型并不是就是簡單的繼承,而是對基類進行了擴展,使之變成一個帶指向箭頭(對象引用)的對象類型也就是InnerHandler屬性,InnerHandler屬性的值就是在當前這個消息處理程序的下一個消息處理程序,DelegatingHandler類型對基類的擴展,HttpMessageHandler類型我感覺它的存在就是一個規范,從管道中的第一個處理程序開始一直到最后一個,除了最后一個消息處理程序,其他的都是DelegatingHandler類型的子類(當然也是HttpMessageHandler的子類),最后一個消息處理程序是直接繼承自HttpMessageHandler類型,因為它是最后一個處理程序了不必要有指向下一個處理程序的屬性,這種對職責的劃分真的很優美,說不出好在哪就是覺得漂亮。

HttpServer消息處理程序(實現類-管道頭)

public class HttpServer : DelegatingHandler    {        public HttpServer();        public HttpServer(HttpConfiguration configuration);        public HttpServer(HttpMessageHandler dispatcher);        public HttpServer(HttpConfiguration configuration, HttpMessageHandler dispatcher);        public HttpConfiguration Configuration { get; }        public HttpMessageHandler Dispatcher { get; }        protected override void Dispose(bool disposing);        protected virtual void Initialize();        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);    }

HttpServer類型繼承自DelegatingHandler類型,是作為管道中第一個消息處理的,要說明的是重載的這些構造函數,如果只是采用默認的構造函數的話,HttpConfiguration類型的參數默認的就是實例化HttpConfiguration類型,而HttpMEssageHandler類型的參數默認的是實例化HttpRoutingDispatcher類型的消息處理器,并且是賦值到Dispatcher屬性的,是作為管道中最后一個消息處理器的(真正的操作實際不是它,后面篇幅會有講到)。

HttpRoutingDispatcher消息處理程序(實現類-管道尾)

    public class HttpRoutingDispatcher : HttpMessageHandler    {        // Fields        private readonly HttpConfiguration _configuration;        private readonly HttpMessageInvoker _defaultInvoker;        // Methods        public HttpRoutingDispatcher(HttpConfiguration configuration);        public HttpRoutingDispatcher(HttpConfiguration configuration, HttpMessageHandler defaultHandler);        private static void RemoveOptionalRoutingParameters(IDictionary<string, object> routeValueDictionary);        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken);    }

HttpRoutingDispatcher類型繼承自HttpMessageHandler類型,上面也說到過它是作為在管道中最后一個消息處理器的,說是可以這么說,但是真正執行的卻不是它,而是在執行重載的構造函數的時候會默認的生成HttpControllerDispatcher類型作為HttpMessageHandler類型的構造函數參數,這里就不對它進行過多的闡述了,后面的篇幅自然會說明的很詳細。

下面我們來看一下ASP.NET Web API管道的大概示意圖。

圖1

(藍色線條表示請求,紅色線條表示響應)

這樣的示意圖說明的不是太清晰下面我們用《ASP.NET Web API 開篇介紹示例》中的SelfHost環境下的示例來演示一下,這樣大家自然就會清楚這個流程了。

首先我們定義一個消息處理器類型命令為CustomDelegatingHandler,并且繼承自DelegatingHandler類型。示例代碼如下

代碼1-1

    public class CustomDelegatingHandler : DelegatingHandler    {        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)        {            Console.WriteLine(request.RequestUri.OriginalString + "____" + request.Method.Method);            Task<HttpResponseMessage> responseMessage = base.SendAsync(request, cancellationToken);            Console.WriteLine(responseMessage.Result.RequestMessage.Method.Method);            return responseMessage;        }   }

隨之我們在SelfHost環境下的服務端在注冊路由之后注冊剛才我們新建的消息處理程序對象,示例代碼如下:

代碼1-2

        static void Main(string[] args)        {            HttpSelfHostConfiguration selfHostConfiguration =                new HttpSelfHostConfiguration("http://localhost/selfhost");            using (HttpSelfHostServer selfHostServer = new HttpSelfHostServer(selfHostConfiguration))            {                selfHostServer.Configuration.Routes.MapHttpRoute(                    "DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });                RegistrationMessageHandler(selfHostServer.Configuration);                selfHostServer.OpenAsync();                Console.WriteLine("服務器端服務監聽已開啟");                Console.Read();            }        }        static void RegistrationMessageHandler(HttpConfiguration httpconfiguration)        {            httpconfiguration.MessageHandlers.Add(new HttpMessageHandlers.CustomDelegatingHandler());        }

在注冊完畢,并且服務器已經啟動開啟請求監聽,客戶端也隨之發出請求之后,我們再來看一下客戶端發出的請求以及類型,如下圖。

圖2

這個時候我們再來看一下服務端管道處理情況,如下圖。

圖3

每一個紅框圈中的部分都表示著一個請求和響應的流程跟圖2中的所有請求是對應的,可以從代碼1-1中就可以看出輸出的內容。

如果說這樣的示例并不不明顯,不能讓人很清楚明白的了解管道的執行過程以及順序,那我們定義兩個處理程序,并且修改代碼1-1,示例代碼如下:

代碼1-3

    public class CustomDelegatingHandler : DelegatingHandler    {        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)        {            Console.WriteLine(this.GetType().Name + ":" + request.RequestUri.OriginalString + "____" + request.Method.Method);            Task<HttpResponseMessage> responseMessage = base.SendAsync(request, cancellationToken);            Console.WriteLine(this.GetType().Name + ":" + responseMessage.Result.RequestMessage.Method.Method);            return responseMessage;        }    }    public class CustomDelegatingHandler_1 : DelegatingHandler    {        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)        {            Console.WriteLine(this.GetType().Name + ":" + request.RequestUri.OriginalString + "____" + request.Method.Method);            Task<HttpResponseMessage> responseMessage = base.SendAsync(request, cancellationToken);            Console.WriteLine(this.GetType().Name + ":" + responseMessage.Result.RequestMessage.Method.Method);            return responseMessage;        }}

隨之我們注冊管理處理程序的地方也要新增一個消息處理程序,示例代碼如下:

代碼1-4

        static void RegistrationMessageHandler(HttpConfiguration httpconfiguration)        {            httpconfiguration.MessageHandlers.Add(new HttpMessageHandlers.CustomDelegatingHandler());            httpconfiguration.MessageHandlers.Add(new HttpMessageHandlers.CustomDelegatingHandler_1());        }

這個時候按照圖2之前的那段說明操作,再看一下服務端的管道處理情況,請求還是那些個請求,看下示意圖如下:

上一篇:說說ASP.NET的IsPostBack

下一篇:擴展方法

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 旬邑县| 山东省| 栾城县| 遵义市| 读书| 蚌埠市| 崇义县| 商城县| 湾仔区| 行唐县| 罗江县| 崇义县| 行唐县| 乌苏市| 平远县| 抚顺县| 米脂县| 五河县| 岳阳县| 塘沽区| 沁阳市| 武威市| 德惠市| 华安县| 勃利县| 洛南县| 银川市| 河津市| 沧州市| 读书| 大姚县| 凤翔县| 华亭县| 新蔡县| 海伦市| 和田县| 宁波市| 吉隆县| 舒兰市| 阳山县| 平凉市|