首页 > 解决方案 > Asp.Net Core 2.x 中间件语法

问题描述

我在 Startup.Configure() 方法中遇到了几种直接编写简单中间件的方法:

// Syntax 1.
app.Use((context, next) =>
{
    context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    return next();
});

// Syntax 2.
app.Use(async (context, next) =>
{
    context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    await next();
});

// Syntax 3.
app.Use(async (context, next) =>
{
    context.Response.Headers.Add("X-Content-Type-Options", "nosniff");
    await next.Invoke();
});

// Syntax 4.
app.Use(next =>
{
    return ctx =>
    {
        ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff");
        return next(ctx);
    };
});

它们都一样吗?

标签: c#asp.net-core.net-coremiddleware

解决方案


语法 1 和语法 2 在功能上有所不同。语法 1 不等待next()完成其Task. 语法 1 将一个普通的 lambda 函数传递给Use并返回,Task而不等待它完成。语法 2 传递一个asynclambda 函数并且是awaiting返回Task之前。关键字告诉应用程序暂停执行,await直到next()任务完成。在您的示例代码中,这可能不会导致功能上的差异,但有时等待 aTask完成会产生影响。

语法 2 和语法 3 在语法上不同,但在功能上相同。语法 2 只是语法 3 的用户友好版本。参见Func<T>() 与 Func<T>.Invoke()

语法 1 和语法 4 在语法上不同但功能相同。语法 1 只是语法 4 的用户友好包装器。请参阅UseExtension.cs

// syntax 1,2,3 use this 
public static IApplicationBuilder Use(
    this IApplicationBuilder app, 
    Func<HttpContext, Func<Task>, Task> middleware)
{
    // which calls into syntax4
    return app.Use(next =>
    {
        return context =>
        {
            Func<Task> simpleNext = () => next(context);
            return middleware(context, simpleNext);
        };
    });
}

推荐阅读