欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

asp.net core 系列之中间件进阶篇-编写自定义中间件(middleware)

程序员文章站 2022-07-02 16:47:49
中间件是被用到管道(pipeline)上来处理请求(request)和响应的(response)。 asp.net core 本身提供了一些内置的中间件,但是有一些场景,你可能会需要写一些自定义的中间件。 1. 创建一个使用匿名委托的中间件组件的形式 注:app.use中return next()会 ......

 

中间件是被用到管道(pipeline)上来处理请求(request)和响应的(response)。

asp.net core 本身提供了一些内置的中间件,但是有一些场景,你可能会需要写一些自定义的中间件。

 

1. 创建一个使用匿名委托的中间件组件的形式

public class startup
{
    public void configure(iapplicationbuilder app)
    {
        app.use((context, next) =>
        {
            var culturequery = context.request.query["culture"];
            if (!string.isnullorwhitespace(culturequery))
            {
                var culture = new cultureinfo(culturequery);

                cultureinfo.currentculture = culture;
                cultureinfo.currentuiculture = culture;
            }

            // call the next delegate/middleware in the pipeline
            return next();
        });

        app.run(async (context) =>
        {
            await context.response.writeasync(
                $"hello {cultureinfo.currentculture.displayname}");
        });

    }
}

 注:app.use中return next()会传递到下一个中间件继续执行;而仅仅只使用app.use 的用法和app.run相同,即不会再传递到下一个中间件,在此作为请求处理的结束

2.把中间件的委托封装到类里面,即把中间件写成一个类的形式

using microsoft.aspnetcore.http;
using system.globalization;
using system.threading.tasks;

namespace culture
{
    public class requestculturemiddleware
    {
        private readonly requestdelegate _next;

        public requestculturemiddleware(requestdelegate next)
        {
            _next = next;
        }

        public async task invokeasync(httpcontext context)
        {
            var culturequery = context.request.query["culture"];
            if (!string.isnullorwhitespace(culturequery))
            {
                var culture = new cultureinfo(culturequery);

                cultureinfo.currentculture = culture;
                cultureinfo.currentuiculture = culture;

            }

            // call the next delegate/middleware in the pipeline
            await _next(context);
        }
    }
}

 

然后,再使用一个中间件扩展方法,通过iapplicationbuilder使用中间件

using microsoft.aspnetcore.builder;

namespace culture
{
    public static class requestculturemiddlewareextensions
    {
        public static iapplicationbuilder userequestculture(
            this iapplicationbuilder builder)
        {
            return builder.usemiddleware<requestculturemiddleware>();
        }
    }
}

 

最后,在 startup.configure 中调用中间件

public class startup
{
    public void configure(iapplicationbuilder app)
    {
        app.userequestculture();  //调用中间件

        app.run(async (context) =>
        {
            await context.response.writeasync(
                $"hello {cultureinfo.currentculture.displayname}");
        });

    }
}

 

另外,这里还有一点,这个地方不是很懂,说下自己的理解,欢迎大佬指正

当中间件中注入的还有其他service(官方叫 a scoped service )时,需要使用的是invoke方法,而不是invokeasync方法

public class custommiddleware
{
    private readonly requestdelegate _next;

    public custommiddleware(requestdelegate next)
    {
        _next = next;
    }

    // imyscopedservice is injected into invoke
    public async task invoke(httpcontext httpcontext, imyscopedservice svc)
    {
        svc.myproperty = 1000;
        await _next(httpcontext);
    }
}

这里,invoke和invokeasync是不是相同,还是说就仅仅是命名不同,其他用法都一样?

欢迎指正

 

参考网址:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-2.2