在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 // ... } }