zoukankan      html  css  js  c++  java
  • [ASP.NET Core] Middleware

    前言

    本篇文章介绍ASP.NET Core里,用来处理HTTP封包的Middleware,为自己留个纪录也希望能帮助到有需要的开发人员。

    结构

    • 在ASP.NET Core里,每个从「浏览器传入」的HTTP Request封包,会被系统封装为「HttpRequest对象」,并且配置默认的HttpResponse对象、Session对象、ClaimsPrincipal对象...等等物件。接着将这些对象,封装成为一个「HttpContext对象」,用来提供ASP.NET Core后续使用。

      结构01

    • ASP.NET Core在收到HttpContext之后,会把它交给一个「Pipeline」去处理。这个Pipeline里面配置很多「Middleware」。系统会将HttpContext,依序传递给Pipeline里的Middleware去处理。每个Middleware会依照自己内部的程序逻辑,来运算处理HttpContext,并且变更HttpContext所封装的对象内容。

      结构02

    • ASP.NET Core在收到经由Middleware处理完毕的HttpContext之后,就会取出其中所封装的HttpResponse对象。然后依照这个HttpResponse对象,来建立从「服务器回传」的HTTP Response封包内容。

      结构03

    • ASP.NET Core经由上述的系统结构,完成HTTP Request封包输入、HTTP Response封包输出的工作流程。

      结构04

    开发

    Invoke

    [ASP.NET Core] Getting Started这篇文章里,提供了一个ASP.NET Core的Middleware范例:HelloWorldMiddleware。在这个范例里,Middleware透过实做Invoke方法,来提供自己所封装的程序逻辑。

    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;
        }
    }
    

    开发01

    HttpContext.Request

    在实做Middleware.Invoke方法的时候,开发人员可以透过HttpContext.Request,来取得从「浏览器传入」的HTTP Request封包内容。在下列的范例程序代码里,就是透过HttpContext.Request的Path、QueryString两个属性,来分别取得HTTP Request封包的URL路径与QueryString内容。

    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;
        }
    }
    

    开发02

    HttpContext.Response

    同样在实做Middleware.Invoke方法的时候,开发人员可以透过HttpContext.Response,来设定从「服务器回传」的HTTP Response封包内容。在下列的范例程序代码里,就是透过HttpContext.Response的WriteAsync方法、StatusCode属性,来分别设定HTTP Response封包的Content与StatusCode。

    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;
        }
    }
    

    开发03

    Exception

    而在实做Middleware.Invoke方法的时候,如果程序代码里发生了预期之外的Exception。ASP.NET Core预设会使用「500 Internal Server Error」,这个StatusCode来通报系统内部发生异常。 在下列的范例程序代码里,就是直接抛出一个例外错误,交由ASP.NET Core的错误处理机制去处理。

    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;
        }
    }
    

    开发04

    RequestDelegate

    建立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
            // ...
        }
    }
    

    参考

  • 相关阅读:
    脚本——1-100的和
    脚本——删除文件为0大小的文件
    脚本——ping网址
    脚本——大于5k的文件有
    脚本——九九乘法表
    第十天:小数与随机数
    第九天:单元测试
    第八天:错误异常处理
    第七天(1):包与模块管理
    第七天(2):面向对象编程
  • 原文地址:https://www.cnblogs.com/clark159/p/5974280.html
Copyright © 2011-2022 走看看