【问题标题】:Asp.Net Core 2.x middleware syntaxAsp.Net Core 2.x 中间件语法
【发布时间】:2018-06-20 01:33:53
【问题描述】:

我在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);
    };
});

它们都一样吗?

【问题讨论】:

  • This 可能值得一看 1 vs 2

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


【解决方案1】:

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

语法 2 和语法 3 在语法上不同但功能相同。语法 2 只是语法 3 的用户友好版本。请参阅Func<T>() vs 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);
        };
    });
}

【讨论】:

    【解决方案2】:

    语法4使用IApplicationBuilderUse方法

    IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
    

    语法 1、2 和 3 正在使用 IApplicationBuilder 的扩展方法,它是语法 4 中先前方法的包装。这是实现

    public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware)
    {
        return app.Use(next =>
        {
            return context =>
            {
                Func<Task> simpleNext = () => next(context);
                return middleware(context, simpleNext);
            };
        });
    }
    

    对于语法 2 和 3,next.Invoke()next() 之间没有区别。它们都编译为相同的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-03
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多