asp.net-core - 我的中间件将如何在管道中进行?
问题描述
我目前在 .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 的标题。如果没有链接,这怎么可能?
解决方案
如果路径不满足,app.usewelcomepage 将如何调用下一个中间件 app.run?我以为我们总是需要 await.next() ?
是的,我们确实需要一个await next()
. 但是await next()
已经在WelcomePageMiddleware
. 更多详细信息,请参见 的源代码WelcomePageMiddleware
。这里app.UseWelcomePage(...)
只不过是一个最终调用中间件的扩展方法:
return app.UseMiddleware<WelcomePageMiddleware>(Options.Create(options));
调用 是中间件的责任next
,而不是扩展方法。
附带说明一下,通常有 4 种中间件:
- 原始风格:
next => context => { /* ... */ }
- 内联样式:
(context,next)=>{ /* ... */ })
- 基于工厂的中间件:从
IMiddleware
接口继承的类。 - 约定俗成的中间件:没有接口的类。
在这些中间件中,我们调用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>
或一个空的标题。
推荐阅读
- r - 如何使用 `r` 仅将我的 R 命令的某些部分嵌入到 R markdown 文档中?
- javascript - 更新渲染元素(不可变)
- javascript - 通过数组变量制作模式
- firebase - Firebase 托管显示已连接,但当我尝试打开 URL 时显示未找到站点
- java - org.hibernate.WrongClassException:对象 [id=null] 不是指定的子类
- html - bootstrap 4.3.1 导航栏在链接点击时不折叠
- jquery - 如何在引用 jQuery 对象的同时遍历多个“嵌套”DOM 元素?
- ruby-on-rails - 我看到用于获取帖子的 sql 查询,即使它正在缓存数据
- python - 从列表中拉取
- laravel - Laravel 5 - 如何更改 route() 和 assets() url