asp.net core 中间件

ASP.NET Core的处理流程是一个管道,而中间件是装配到管道中的用于处理请求和响应的组件。中间件按照装配的先后顺序执行,并决定是否进入下一个组件。中间件管道的处理流程如下图(图片来源于官网):

Use方法

使用方法:.net core web应用程序中,在Startup.cs中的Configure方法中加入如下代码配置中间件

            #region 使用Use装配中间件到请求处理管道中
            app.Use(async (context, next) =>
            {
                if (!context.Response.HasStarted)
                {
                    Console.WriteLine("MyMiddleware1 Before next");

                    // 等待下一个中间件处理完成
                    await next();

                    Console.WriteLine("MyMiddleware1 after next");
                }
            });

            app.Use(async (context, next) =>
            {
                if (!context.Response.HasStarted)
                {
                    Console.WriteLine("MyMiddleware2 Before next");

                    // 等待下一个中间件处理完成
                    await next();

                    Console.WriteLine("MyMiddleware2 after next");
                }
            });
            #endregion

这时使用的Use扩展方法定义如下

public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware)

Run方法

使用方法:同样在Startup.cs中的Configure方法中加入如下代码

            #region 使用Run
            app.Run(async context => {
                await context.Response.WriteAsync("Hello from 2nd delegate.");
            });
            #endregion

页面运行效果:

 

 

自定义中间件类

自定义中间件类有如下约定:

invoke或invokeasync第一个参数必须是HttpContext不然报错(The 'Invoke' or 'InvokeAsync' method's first argument must be of type 'HttpContext'.”)

自定义的中间件类如下:

    #region 第1步:自定义中间件类
    public class MyMiddleware1
    {
        private readonly RequestDelegate _next;

        // 约定1:具有参数类型为RequestDelegate的公共构造函数
        public MyMiddleware1(RequestDelegate next)
        {
            _next = next;
        }

        // 约定2:具有Invoke/InvokeAsync的公共方法,第一个参数类型为HttpContext ,返回Task
        // 如果中间件里面需要使用其他范围内服务,请将这些服务添加到 Invoke 方法的签名
        public async Task InvokeAsync(HttpContext context, IService1 service1)
        {
            service1.TestMethod();

            await _next(context);
        }
    }
    #endregion

    #region  第2步:定义中间件扩展方法,公开中间件
    public static class MiddlewareExtensions
    {
        public static IApplicationBuilder UseMyMiddleware1(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MyMiddleware1>();
        }
    }
    #endregion

    #region 第3步:定义中间件使用的依赖服务
    public interface IService1 {
        void TestMethod();
    }

    public class Service1 : IService1
    {
        public void TestMethod()
        {
            Console.WriteLine("Service1");
        }
    }
    #endregion

    #region 第4步:在扩展方法中添加依赖服务注册
    public static class IServiceCollectionExtension
    {
        public static IServiceCollection AddService1(this IServiceCollection services)
        {
            return services.AddScoped<IService1, Service1>();
        }
    }
    #endregion

在Startup中的ConfigureServices方法中注册服务

            #region 第5步,注册服务
            services.AddService1();
            #endregion

在Startup中的Configure方法中使用中间件

            #region 第6步:在Configure中使用自定义的中间件
            app.UseMyMiddleware1();
            #endregion

 

参考链接:

https://www.cnblogs.com/youring2/p/10924705.html

posted @ 2021-01-09 17:04  温故纳新  阅读(92)  评论(0编辑  收藏  举报