在ASP.NET Core裏,每一個從「瀏覽器傳入」的HTTP Request封包,會被系統封裝爲「HttpRequest對象」,而且配置默認的HttpResponse對象、Session對象、ClaimsPrincipal對象...等等物件。接着將這些對象,封裝成爲一個「HttpContext對象」,用來提供ASP.NET Core後續使用。瀏覽器
ASP.NET Core在收到HttpContext以後,會把它交給一個「Pipeline」去處理。這個Pipeline裏面配置不少「Middleware」。系統會將HttpContext,依序傳遞給Pipeline裏的Middleware去處理。每一個Middleware會依照本身內部的程序邏輯,來運算處理HttpContext,而且變動HttpContext所封裝的對象內容。服務器
ASP.NET Core在收到經由Middleware處理完畢的HttpContext以後,就會取出其中所封裝的HttpResponse對象。而後依照這個HttpResponse對象,來創建從「服務器回傳」的HTTP Response封包內容。asp.net
ASP.NET Core經由上述的系統結構,完成HTTP Request封包輸入、HTTP Response封包輸出的工做流程。async
在[ASP.NET Core] Getting Started這篇文章裏,提供了一個ASP.NET Core的Middleware範例:HelloWorldMiddleware。在這個範例裏,Middleware透過實作Invoke方法,來提供本身所封裝的程序邏輯。.net
public class HelloWorldMiddleware { // Fields private readonly RequestDelegate _next; // Constructors public HelloWorldMiddleware(RequestDelegate next) { _next = next; } // Methods public Task Invoke(HttpContext context) { // Response context.Response.WriteAsync("Hello World!"); // Return return Task.CompletedTask; } }
在實作Middleware.Invoke方法的時候,開發人員能夠透過HttpContext.Request,來取得從「瀏覽器傳入」的HTTP Request封包內容。在下列的範例程序代碼裏,就是透過HttpContext.Request的Path、QueryString兩個屬性,來分別取得HTTP Request封包的URL路徑與QueryString內容。code
public class HelloWorldMiddleware { // Fields private readonly RequestDelegate _next; // Constructors public HelloWorldMiddleware(RequestDelegate next) { _next = next; } // Methods public Task Invoke(HttpContext context) { // Request string path = context.Request.Path.ToString(); string queryString = context.Request.QueryString.ToString(); string message = string.Format("path={0}, queryString={1}", path, queryString); // Response context.Response.WriteAsync(message); // Return return Task.CompletedTask; } }
一樣在實作Middleware.Invoke方法的時候,開發人員能夠透過HttpContext.Response,來設定從「服務器回傳」的HTTP Response封包內容。在下列的範例程序代碼裏,就是透過HttpContext.Response的WriteAsync方法、StatusCode屬性,來分別設定HTTP Response封包的Content與StatusCode。orm
public class HelloWorldMiddleware { // Fields private readonly RequestDelegate _next; // Constructors public HelloWorldMiddleware(RequestDelegate next) { _next = next; } // Methods public Task Invoke(HttpContext context) { // Response context.Response.StatusCode = 404; context.Response.WriteAsync("Not Found"); // Return return Task.CompletedTask; } }
而在實作Middleware.Invoke方法的時候,若是程序代碼裏發生了預期以外的Exception。ASP.NET Core預設會使用「500 Internal Server Error」,這個StatusCode來通報系統內部發生異常。 在下列的範例程序代碼裏,就是直接拋出一個例外錯誤,交由ASP.NET Core的錯誤處理機制去處理。htm
public class HelloWorldMiddleware { // Fields private readonly RequestDelegate _next; // Constructors public HelloWorldMiddleware(RequestDelegate next) { _next = next; } // Methods public Task Invoke(HttpContext context) { // Exception throw new Exception(); // Return return Task.CompletedTask; } }
創建Middleware的時候,開發人員能夠透過建構子所傳入的RequestDelegate,來參考到Pipeline裏的下一個Middleware。透過調用RequestDelegate,就能夠調用Pipeline裏的下一個Middleware的Invoke方法。在下列的範例程序代碼裏,就是透過調用RequestDelegate,來調用Pipeline裏的下一個Middleware的Invoke方法,藉此串接其餘Middleware的程序邏輯。對象
public class HelloWorldMiddleware { // Fields private readonly RequestDelegate _next; // Constructors public HelloWorldMiddleware(RequestDelegate next) { _next = next; } // Methods public async Task Invoke(HttpContext context) { // Do Something 01 //.... // Next await _next.Invoke(context); // Do Something 02 // ... } }