首页 > 解决方案 > 我的中间件将如何在管道中进行?

问题描述

我目前在 .NET Core (以及任何与 .NET 相关的东西)非常陌生。我正在 Pluralsight 上在线学习一门课程,到目前为止,我们已经生成了以下方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IGreeter greeter, ILogger<Startup> logger)
        {
            app.Use(next =>
            {
            return async context =>
                {
                    logger.LogInformation("Request Incoming");
                    if (context.Request.Path.StartsWithSegments("/my"))
                    {
                        logger.LogInformation("Inside first Middleware!");
                        await context.Response.WriteAsync("Inside first Middleware");
                    }
                    else
                    {
                        logger.LogInformation("Request going to next Middleware");
                        //await next(context);
                    }
                };
            });

            app.UseWelcomePage(new WelcomePageOptions
            {
                Path = "/wp"
            });

            app.Run(async (context) =>
            {
                var greeting = greeter.getMessageOfTheDay();
                await context.Response.WriteAsync(greeting);
            });
        }

我对管道在某些情况下的工作方式有些困惑。

例如,如果我要删除第一个中间件 app.use 和 app.UseWelcomePage 成为第一个中间件。如果路径不满足,app.usewelcomepage 将如何调用下一个中间件 app.run?我以为我们总是需要 await.next() ?在我的情况下 app.run 将执行。

对于我的第二个问题,使用下面的代码,当我在第一个中间件中注释掉 await.next() 时,无论我运行 IISExpress,浏览器正在加载并考虑要做什么。在标题选项卡中,会简要显示来自 UseWelcomePage 的标题。如果没有链接,这怎么可能?

标签: asp.net-core

解决方案


如果路径不满足,app.usewelcomepage 将如何调用下一个中间件 app.run?我以为我们总是需要 await.next() ?

是的,我们确实需要一个await next(). 但是await next()已经在WelcomePageMiddleware. 更多详细信息,请参见 的源代码WelcomePageMiddleware。这里app.UseWelcomePage(...)只不过是一个最终调用中间件的扩展方法:

return app.UseMiddleware<WelcomePageMiddleware>(Options.Create(options));

调用 是中间件的责任next,而不是扩展方法。

附带说明一下,通常有 4 种中间件:

  1. 原始风格:next => context => { /* ... */ }
  2. 内联样式:(context,next)=>{ /* ... */ })
  3. 基于工厂的中间件:从IMiddleware接口继承的类。
  4. 约定俗成的中间件:没有接口的类。

在这些中间件中,我们调用await next()await next(context) 调用下一个中间件。与第一种、第三种、第四种中间件一起使用时,我们应该使用await next(context)而不是await next().

使用下面的代码,当我在第一个中间件中注释掉 await.next() 时,无论我运行 IISExpress,浏览器正在加载并考虑要做什么。在标题选项卡中,会简要显示来自 UseWelcomePage 的标题。如果没有链接,这怎么可能?

不确定您的意思是“如果没有链接”。但是,如果您在第一个中间件中注释行await next(context),则第二个和第三个中间件将永远不会更改处理请求。如果您在注释掉之前已经在浏览器中呈现了一个 WelcomePage await next(context),然后注释掉第一个await next(context),浏览器将在不更改标题的情况下挂起几秒钟,但如果您等待足够的时间,您会得到类似<title>Can't reach this page</title>或一个空的标题。


推荐阅读