欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品

主頁 > 知識庫 > 解讀ASP.NET 5 & MVC6系列教程(6):Middleware詳解

解讀ASP.NET 5 & MVC6系列教程(6):Middleware詳解

熱門標簽:西寧呼叫中心外呼系統線路商 外呼電話機器人成本 網絡電話外呼系統上海 蘇州如何辦理400電話 聯通官網400電話辦理 百應電話機器人外呼系統 400電話辦理怎么樣 地圖標注軟件免費下載 臨沂智能電話機器人加盟

在第1章項目結構分析中,我們提到Startup.cs作為整個程序的入口點,等同于傳統的Global.asax文件,即:用于初始化系統級的信息(例如,MVC中的路由配置)。本章我們就來一一分析,在這里如何初始化這些系統級的信息。

新舊版本之間的Pipeline區別

ASP.NET 5和之前版本的最大區別是對HTTP Pipeline的全新重寫,在之前的版本中,請求過濾器的通常是以HttpModule為模塊組件,這些組件針對HttpApplication里定義的各個周期內的事件進行響應,從而用于實現認證、全局錯誤處理、日志等功能。傳統的Form表單認證就是一個HTTPModuleHTTPModule不僅能夠過濾Request請求,還可以和Response響應進行交互并修改。這些HTTPModule組件都繼承于IHttpModule接口,而該接口是位于System.Web.dll中。

HttpModule代碼不僅可以在Global.asax中的各事件周期中進行添加,還可以單獨編譯成類庫并在web.config中進行注冊。

新版的ASP.NET 5拋棄了重量級的System.Web.dll,相應地引入了Middleware的概念,Middleware的官方定義如下:

Pass through components that form a pipeline between a server and application to inspect, route, or modify request and response messages for a specific purpose.
在服務器和應用程序之間的管線Pipeline之間,針對特定的目的,穿插多個Middleware組件,從而對request請求和response響應進行檢
查、路由、或修改。

該定義和傳統的HttpModule以及HttpHandler特別像。

Middleware的注冊和配置

在ASP.NET5中,request請求管線(Pipeline)的訪問是在Startup類中進行的,該類時一個約定類,并且里面的ConfigureServices方法、Configure方法、以及相應的參數也是事先約定的,所以不能進行改動。

Middleware中的依賴處理:ConfigureServices方法

在ASP.NET5中的各種默認的Middleware中,都使用了依賴注入的功能,所以在使用Middleware中的功能時,需要提前將依賴注入所需要的類型及映射關系都注冊到依賴注入管理系統中,即IServiceCollection集合,而ConfigureServices方法接收的就一個IServiceCollection類型的參數,該參數就是所有注冊過類型的集合,通過原生的依賴注入組件進行管理(關于ASP.NET5中的依賴注入,我們會在單獨章節中進行講解),在該方法內,我們可以向該集合中添加新的類型和類型映射關系,示例如下:

// Add MVC services to the services container.
services.AddMvc();

示例中的代碼用于向系統添加Mvc模塊相關的Service類型以支撐MVC功能,該方法是一個擴展方法,用于在集合中添加與MVC相關的多個類型。

Middleware的注冊和配置:Configure方法

Configure方法的簽名如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
 // ...
}

Configure方法接收了三個參數:IApplicationBuilder類型的參數用于構建整個應用程序的配置信息,IHostingEnvironment類的env參數用于訪問系統環境變量相關的內容,ILoggerFactory類型的loggerfactory用于日志相關的內容處理,其中IApplicationBuilder類型的參數最為重要,該參數實例app上有一系列的擴展方法用于將各種Middleware注冊到request請求管線(Pipeline)中。這種方式和之前ASP.NET中的HTTP管線的主要區別是:新版本中的組合模型替換了舊版本中的事件模型。這也就要求,在新版ASP.NET中,Middleware組件注冊的順序是非常重要的,因為后一個組件可能要使用到前一個組件,所以必須按照依賴的先后順序進行注冊,舉例如下,當前MVC項目的模板代碼示例如下:

// Add static files to the request pipeline.
app.UseStaticFiles();

// Add cookie-based authentication to the request pipeline.
app.UseIdentity();

// Add MVC to the request pipeline.
app.UseMvc(routes =>{ /*...*/});

示例中的UseStaticFilesUseIdentityUseMvc都是IApplicationBuilder上的擴展方法,在擴展方法中,都會通過調用擴展方法app.UseMiddleware方法,最終再調用app.Use方法來注冊新的Middleware,該方法定義如下:

public interface IApplicationBuilder
{
 //...
 IApplicationBuilder Use(FuncRequestDelegate, RequestDelegate> middleware);
}

通過代碼,可以看出,middleware是FuncRequestDelegate, RequestDelegate>的一個實例,該Func接收一個RequestDelegate的參數,并返回一個RequestDelegate類型的值。RequestDelegate的源碼如下:

public delegate Task RequestDelegate(HttpContext context);

通過源碼,我們可以看出,RequestDelegate是一個委托函數,其接收HttpContext類型的實例,并返回一個Task類型的異步對象。也就是說RequestDelegate是一個可以返回自身RequestDelegate類型函數的函數,整個ASP.NET也就是利用這種方式構建了管線(Pipelien)的組成,在這里,每個middleware都鏈式到下一個middleware上,并在整個過程中可以對HttpConext對象進行修改或維護,當然,HttpContext中就包括了我們常操作的HttpRequestHttpResponse實例對象。

注意:HttpContextHttpRequestHttpResponse在ASP.NET 5中都是重新定義的新類型。

Middleware的定義

既然每個middleare都是FuncRequestDelegate, RequestDelegate>的一個實例,那是不是Middleware的定義要滿足一個規則?是繼承于一個抽象基類還是借口?通過翻查相關的代碼,我們看到,Middleware是基于約定的形式來定義的,具體約定規則如下:

構造函數的第一個參數必須是處理管線中的下一個處理函數,即RequestDelegate;必須有一個 Invoke 函數, 并接受上下文參數(即HttpContent), 然后返回 Task;

示例如下:

public class MiddlewareName
{
 RequestDelegate _next;

 public MiddlewareName(RequestDelegate next)
 {
  _next = next;// 接收傳入的RequestDelegate實例
 }

 public async Task Invoke(HttpContext context)
 {
  // 處理代碼,如處理context.Request中的內容

  Console.WriteLine("Middleware開始處理");

  await _next(context);

  Console.WriteLine("Middleware結束處理");

  // 處理代碼,如處理context.Response中的內容
 }
}

通過該模板代碼可以看到,首先一個Middleware的構造函數要接收一個RequestDelegate的實例,先保存在一個私有變量里,然后通過調用Invoke方法(并接收HttpContent實例)并返回一個Task,并且在調用Invoke的方法中,要通過await _next(context);語句,鏈式到下一個Middleware上,我們的處理代碼主要就是在鏈式語句的前后執行相關的代碼。

舉個例子,如果我們要想記錄頁面的執行時間,首先,我們先定義一個TimeRecorderMiddleware,代碼如下:

public class TimeRecorderMiddleware
{
 RequestDelegate _next;

 public TimeRecorderMiddleware(RequestDelegate next)
 {
  _next = next;
 }

 public async Task Invoke(HttpContext context)
 {
  var sw = new Stopwatch();
  sw.Start();


  await _next(context);

  var newDiv = @"div id=""process"">頁面處理時間:{0} 毫秒/div>/body>";
  var text = string.Format(newDiv, sw.ElapsedMilliseconds);
  await context.Response.WriteAsync(text);
 }
}

Middleware的注冊有很多種方式,如下是實例型注冊代碼:

app.Use(next => new TimeRecorderMiddleware(next).Invoke);

或者,你也可以使用UseMiddleware擴展方法進行注冊,示例如下:

app.UseMiddlewareTimeRecorderMiddleware>();
//app.UseMiddleware(typeof(TimeRecorderMiddleware)); 兩種方式都可以

當然,你也可以定義一個自己的擴展方法用于注冊該Middleware,代碼如下:

public static IApplicationBuilder UseTimeRecorderMiddleware(this IApplicationBuilder app)
{
 return app.UseMiddlewareTimeRecorderMiddleware>();
}

最后在Startup類的Configure方法內進行注冊,代碼如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
 app.UseTimeRecorderMiddleware(); // 要放在前面,以便進行統計,如果放在Mvc后面的話,就統計不了時間了。

 // 等等
}

編譯,重啟,并訪問頁面,在頁面的底部即可看到頁面的運行時間提示內容。

常用Middleware功能的使用

app.UseErrorPage()
在IHostingEnvironment.EnvironmentName為Development的情況下,才顯示錯誤信息,并且錯誤信息的顯示種類,可以通過額外的ErrorPageOptions參數來設定,可以設置全部顯示,也可以設置只顯示Cookies、Environment、ExceptionDetails、Headers、Query、SourceCode SourceCodeLineCount中的一種或多種。

app.UseErrorHandler("/Home/Error")
捕獲所有的程序異常錯誤,并將請求跳轉至指定的頁面,以達到友好提示的目的。

app.UseStaticFiles()
開啟靜態文件也能走該Pipeline管線處理流程的功能。

app.UseIdentity()
開啟以cookie為基礎的ASP.NET identity認證功能,以支持Pipeline請求處理。

直接使用委托定義Middleware的功能

由于Middleware是FuncRequestDelegate, RequestDelegate>委托類型的實例,所以我們也可以不必定義一個單獨的類,在Startup類里,使用委托調用的方式就可以了,示例如下:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory)
{
 app.Use(new FuncRequestDelegate, RequestDelegate>(next => content => Invoke(next, content)));
 // 其它
}

// 注意Invoke方法的參數
private async Task Invoke(RequestDelegate next, HttpContext content)
{
 Console.WriteLine("初始化組件開始");
 await next.Invoke(content);
 Console.WriteLine("管道下步執行完畢");
}

做個簡便的Middleware基類

雖然有約定方法,但有時候我們在開發的時候往往會犯迷糊,想不起來到底是什么樣的約定,所以,在這里我們可以定義一個抽象基類,然后以后所有的Middleware在定義的時候都繼承該抽象類并重載Invoke方法即可,從而可以避免約定忘記的問題。代碼如下:

/// summary>
/// 抽象基類
/// /summary>
public abstract class AbstractMiddleware
{
 protected RequestDelegate Next { get; set; }
 protected AbstractMiddleware(RequestDelegate next)
 {
  this.Next = next;
 }
 public abstract Task Invoke(HttpContext context);
}

/// summary>
/// 示例Middleware
/// /summary>
public class DemoMiddleware : AbstractMiddleware
{
 public DemoMiddleware(RequestDelegate next) : base(next)
 {
 }
 public async override Task Invoke(HttpContext context)
 {
  Console.WriteLine("DemoMiddleware Start.");
  await Next.Invoke(context);
  Console.WriteLine("DemoMiddleware End.");
 }
}

使用方法和上面的一樣。

終止鏈式調用或阻止所有的Middleware

在有些情況下,當然根據某些條件判斷以后,可能不在需要繼續往下執行下去了,而是想知己誒返回結果,那么你可以在你的Middleware里忽略對await next.Invoke(content);的調用,直接使用·Response.WriteAsync·方法輸出內容。

另外,在有些情況下,你可能需要實現類似之前版本中的handler的功能,即不經常任何Pipeline直接對Response進行響應,新版ASP.NET里提供了一個run方法用于實現該功能,只需要在Configure方法里調用如下代碼即可實現類似的內容輸出。

app.Run(async context =>
{
 context.Response.ContentType = "text/html";
 await context.Response.WriteAsync("Hello World!");
});

關于ASP.NET 5 Runtime的內容,請訪問:https://msdn.microsoft.com/en-us/magazine/dn913182.aspx

遺留問題

在Mvc項目中,所有的依賴注入類型都是通過IServiceProvider實例來獲取的,目前可以通過以下形式獲取該實例:

var services = Context.RequestServices; // Controller中
var services = app.ApplicationServices; // Startup中

獲取了該實例以后,即可通過如下方法來獲取某個類型的對象:

var controller = (AccountController)services.GetService(typeof(AccountController));
// 要判斷獲取到的對象是否為null

如果你引用了Microsoft.Framework.DependencyInjection命名空間的話,還可以使用如下三種擴展方法:

var controller2 = (AccountController)services.GetServiceAccountController>(); 
// 要判斷獲取到的對象是否為null

//如下兩種方式,如果獲取到的AccountController實例為null的話,就會字段拋異常,而不是返回null
var controller3 = (AccountController)services.GetRequiredService(typeof(AccountController));
var controller4 = (AccountController)services.GetRequiredServiceAccountController>();

那么問題來了?如何不在Startup和Controller里就可以獲取到HttpContext和IApplicationBuilder實例以便使用這些依賴注入服務?

如何獲取IApplicationBuilder實例?
答案:在Startup里將IApplicationBuilder實例保存在一個單例中的變量上,后期全站就可以使用了。

如何獲取HttpContext實例?
答案:參考依賴注入章節的普通類的依賴注入

引用:http://www.mikesdotnetting.com/article/269/asp-net-5-middleware-or-where-has-my-httpmodule-gone

您可能感興趣的文章:
  • 利用Asp.Net Core的MiddleWare思想如何處理復雜業務流程詳解

標簽:平涼 中衛 臨夏 清遠 聊城 甘肅 海西 慶陽

巨人網絡通訊聲明:本文標題《解讀ASP.NET 5 & MVC6系列教程(6):Middleware詳解》,本文關鍵詞  解讀,ASP.NET,amp,MVC6,系列,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《解讀ASP.NET 5 & MVC6系列教程(6):Middleware詳解》相關的同類信息!
  • 本頁收集關于解讀ASP.NET 5 & MVC6系列教程(6):Middleware詳解的相關信息資訊供網民參考!
  • 推薦文章
    欧美阿v视频在线大全_亚洲欧美中文日韩V在线观看_www性欧美日韩欧美91_亚洲欧美日韩久久精品
  • <rt id="w000q"><acronym id="w000q"></acronym></rt>
  • <abbr id="w000q"></abbr>
    <rt id="w000q"></rt>
    亚洲欧洲av在线| 久久国产视频网| 99久久婷婷国产综合精品电影| 9.1片黄在线观看| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 精品自拍偷拍视频| 中文一区二区在线观看| 国产精品99久久久久久有的能看| 懂色av粉嫩av浪潮av| 国产日韩欧美a| 国产盗摄一区二区三区| 国产精品69久久久久孕妇欧美| 久久影音资源网| 精品写真视频在线观看| 免费人成又黄又爽又色| 久久蜜桃av一区二区天堂| 久久97超碰色| 人人艹在线视频| 国产精品久久久久一区二区三区 | 国产综合色精品一区二区三区| 精品成人av一区二区三区| 久久只精品国产| 国产黄色成人av| 青青草原在线免费观看| 亚洲美女在线国产| 亚洲视频 中文字幕| 日韩欧美第一区| 国产一区欧美一区| 9999热视频| 一区二区三区精品视频| 熟妇高潮一区二区| 精品久久久久99| 国产经典欧美精品| 色噜噜久久综合| 亚洲综合视频在线观看| 中文字幕日韩三级片| 久久精品亚洲麻豆av一区二区| 懂色av一区二区三区蜜臀| 在线免费亚洲电影| 日韩精品亚洲一区二区三区免费| 欧美狂猛xxxxx乱大交3| 国产精品视频在线看| 亚洲AV无码久久精品国产一区| 9191成人精品久久| 国产一区在线观看麻豆| 在线观看av一区| 人人爽香蕉精品| 欧洲美女女同性互添| 夜夜夜精品看看| 久久美女免费视频| 中文字幕在线不卡一区| 国产麻豆剧传媒精品国产av| 久久精品视频在线免费观看| 99久久er热在这里只有精品66| 91麻豆精品国产无毒不卡在线观看| 黑人巨大精品欧美黑白配亚洲| 色狠狠av一区二区三区| 日本免费新一区视频| 人人澡人人澡人人看| 亚洲成人综合在线| 5566中文字幕| 性久久久久久久久久久久| 永久免费观看片现看| 亚洲一二三四久久| 天天操天天摸天天舔| 亚洲大型综合色站| 永久免费未视频| 日韩高清电影一区| 亚洲一级免费毛片| 久久成人精品无人区| 欧美亚洲国产一卡| 国产精品资源网站| 91精品一区二区三区久久久久久 | 蜜桃视频一区二区三区| 丰满少妇高潮久久三区| 麻豆精品在线视频| 欧美色图12p| 福利电影一区二区| 精品国产乱码久久久久久浪潮| 91免费版在线| 欧美国产日韩在线观看| 亚洲AV无码国产精品| 一区二区三区中文在线| 美国精品一区二区| 人人超碰91尤物精品国产| 欧美艳星brazzers| 国产不卡视频在线播放| 精品久久久久久久久久久久久久久久久| 亚洲一二三四五六区| 女同性恋一区二区三区| 国产精品色噜噜| a级在线免费观看| 午夜久久电影网| 91福利社在线观看| 国产福利一区二区三区视频| 日韩精品中文字幕一区二区三区| 97se亚洲国产综合自在线观| 亚洲国产经典视频| 欧美大波大乳巨大乳| 日日骚欧美日韩| 欧美日韩夫妻久久| 亚洲丝袜在线观看| 综合久久给合久久狠狠狠97色 | 一本久久综合亚洲鲁鲁五月天| 蜜乳av一区二区三区| 8x8x8国产精品| 亚洲区 欧美区| 亚洲美女少妇撒尿| 亚洲国产美女视频| 成熟亚洲日本毛茸茸凸凹| 久久久精品蜜桃| 五月天精品视频| 老司机午夜精品| 欧美电影免费提供在线观看| 久久久久久久穴| 亚洲五码中文字幕| 欧美日韩一区国产| 性生交大片免费看l| 樱花草国产18久久久久| 色av一区二区| 最好看的中文字幕| 亚洲综合激情网| 欧美日韩一二三区| 免费观看污网站| 午夜伦理一区二区| 欧美一级国产精品| 大地资源二中文在线影视观看| 性久久久久久久久久久久| 欧美精选午夜久久久乱码6080| 亚洲成a人无码| 偷拍亚洲欧洲综合| 日韩欧美一卡二卡| 成人国产精品久久久网站| 久久国产三级精品| 国产欧美日本一区二区三区| 国产精品免费在线视频| 成人黄页毛片网站| 亚洲激情av在线| 欧美日韩三级一区二区| av在线播放网址| 麻豆成人久久精品二区三区小说| 欧美精品一区二区久久婷婷| 中文字幕第69页| 成人午夜电影久久影院| 亚洲免费观看高清| 91精品免费在线| 蜜臀久久99精品久久久久久| 国产在线不卡一区| 1区2区3区国产精品| 欧美天堂亚洲电影院在线播放| 丝袜熟女一区二区三区| 免费成人在线影院| 亚洲国产精品国自产拍av| 色噜噜狠狠成人中文综合| 2018国产精品| 久久精品国产在热久久| 国产精品色噜噜| 欧美日韩一区不卡| 香蕉视频黄色在线观看| 国产另类ts人妖一区二区| 亚洲色图视频网站| 欧美一区二区啪啪| 99精品中文字幕| 91丨九色丨国产丨porny| 图片区小说区区亚洲影院| 2023国产一二三区日本精品2022| 成人免费毛片xxx| 亚洲乱妇老熟女爽到高潮的片| 麻豆久久一区二区| ㊣最新国产の精品bt伙计久久| 欧美日高清视频| 久操视频在线观看免费| 99精品国产91久久久久久| 天天射综合影视| 亚洲国产精品高清| 56国语精品自产拍在线观看| 一级片黄色录像| 深田咏美中文字幕| 国产精品一区在线观看乱码| 一区二区三区日韩精品视频| 精品国产免费人成电影在线观看四季 | 欧美日韩亚洲综合在线 欧美亚洲特黄一级| 亚洲久久久久久| 粉嫩高潮美女一区二区三区| 婷婷激情综合网| 中文字幕制服丝袜成人av| 日韩一级黄色大片| 色妹子一区二区| 妺妺窝人体色WWW精品| 麻豆av免费看| 国产精品18久久久久久vr | 91国内精品野花午夜精品| 中文幕无线码中文字蜜桃| 99精品视频在线播放观看| 另类小说视频一区二区| 亚洲激情成人在线| 欧美激情在线观看视频免费| 51精品久久久久久久蜜臀| 一本在线高清不卡dvd| 国产综合精品在线|