• ASP.NET Core实践:中间件


    一、什么是中间件

    ASP.NET Core为你准备了一条产线(HTTP request pipeline)、多道工序(Middleware),最终的产出(Http Response)由经过工序多少及顺序决定。

    1、服装生产线

     ^_^ 男士衬衣 =  │裁剪│→│印个篮球│→│缝制│→│整烫│→│检验│→│包装│

    ^_^ 半成品男士衬衣 =  │裁剪│→│印个篮球│→│结束│  │缝制│→│整烫│→│检验│→│包装│

     ^_^ 女士衬衣 =  │裁剪│→│印个城堡│→│印个萝莉│→│缝制│→│整烫│→│检验│→│包装│

     ^_^ 围裙= │裁剪│→│缝制│→│包装│

    (1)从生产衣服可得出

    默认工序 ——  裁剪、缝制、整烫、检验、包装

    自定义工序 ——  印个篮球、印个城堡、印个萝莉

    产品 ——  男士衬衣、半成品男士衬衣、女士衬衣、围裙

    (2)结论 

    产品 = 组合工序(“默认工序”+“自定义工序”)

    (3)注意 

    A、一般情况下是不会去打乱“默认工序”的顺序(如 剪裁→包装 改为 包装→剪裁),不然可能就四不像了(异常);

    B、“中间件”处理完后可以直接结束(叫 断路/短路),不再往下传递(如 半成品男士衬衣)

    2、官方

    • ASP.NET Core 请求管道包含一系列请求委托(中间件),依次调用

    •  典型应用中的中间件顺序

     二、示例

    1、一切从Configure开始

    (1)Startup里

    public class Startup
    {
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
        //认证中间件
        app.UseAuthentication();

    (2)在主机构建器里

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }
    
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureServices(services =>
                    {
                        services.AddControllersWithViews();
                    })
                    .Configure(app =>
                    {
                //认证中间件
                app.UseAuthentication();

    2、自定义“错误处理中间件”

    问题:中间件的写法是怎样?要分几个类?怎样让代码看上去更优雅?

    思路:请参考“内置的中间件”!ASP.NET Core是开源的!ASP.NET Core是开源的!ASP.NET Core是开源的!

    (1)错误处理

        /// <summary>
        /// 错误处理中间件
        /// </summary>
        public class ErrorHandleMiddleware
        {
            private readonly RequestDelegate _next;
    
            /// <summary>
            /// 初始化实例
            /// </summary>
            /// <param name="next">下一个中间件管道.</param>
            public ErrorHandleMiddleware(RequestDelegate next)
            {
                _next = next ?? throw new ArgumentNullException(nameof(next));
            }
    
            /// <summary>
            /// 执行中间件
            /// </summary>
            /// <param name="context">The <see cref="HttpContext"/>.</param>
            public async Task Invoke(HttpContext context)
            {
                if (context == null)
                {
                    throw new ArgumentNullException(nameof(context));
                }
    
                try
                {
                    await _next(context);
                }
                catch (Exception ex)
                {
                    //异常处理
                    await ResultOperate.DirectFail(context, context.Response.StatusCode, ex.Message);
                }
                finally
                {
                    //根据状态码处理
                    var statusCode = context.Response.StatusCode;
                    var msg = "";
                    switch (statusCode)
                    {
    

    (2)中间件的扩展方法  

        /// <summary>
        /// 添加中间件的扩展方法
        /// </summary>
        public static class ErrorHandleExtensions
        {
            public static IApplicationBuilder UseErrorHandle(this IApplicationBuilder app)
            {
                if (app == null)
                {
                    throw new ArgumentNullException(nameof(app));
                }
    
                return app.UseMiddleware<ErrorHandleMiddleware>();
            }
        }
    

    (3)使用它 - 成为一个名副其实的中间件  

            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                app.UseAbp(options => { options.UseAbpRequestLocalization = false; }); // Initializes ABP framework.
    
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/error");
                }
    
                app.UseHttpsRedirection();
    
                app.UseRouting();
    
                //认证中间件
                app.UseAuthentication();
    
                //错误处理中间件(需要放在“授权中间件”前,不然遇到401就直接断路OVER了)
                app.UseErrorHandle();
    
                //授权中间件
                app.UseAuthorization();    
    

      

     三、参考

    • ASP.NET Core 中间件

    https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.1

    • ASP.NET Core 中的应用启动

    https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/startup?view=aspnetcore-3.1

    • UseAuthorization授权中间件 - 源码

    https://github.com/dotnet/aspnetcore/tree/master/src/Security/Authorization/Policy/src

  • 相关阅读:
    [转] jQuery 操作 JSON 数据
    [转] 8张图学习javascript
    HTML文档类型声明的坑...
    Android 应用内HttpClient 与 WebView 共享 Cookie
    李嘉诚无锡演讲
    keytool 生成 Android SSL 使用的 BKS
    LeetCode-344-反转字符串
    LeetCode-342-4的幂
    LeetCode-338-比特位计数
    LeetCode-326-3的幂
  • 原文地址:https://www.cnblogs.com/hepc/p/13894178.html
Copyright © 2020-2023  润新知