【问题标题】:Why is ASP.NET Core executing a custom middleware only once?为什么 ASP.NET Core 只执行一次自定义中间件?
【发布时间】:2018-10-02 16:21:28
【问题描述】:

我有一个 ASP.NET Core,它带有以下接受 POST 请求的控制器:

[Route("api/v1/tenants/tests")]
public class TestsController : Controller
{
    [HttpPost]       
    public IActionResult Post(string tenantId)
    {
        return Ok();
    }
}

我开发了一个“空”中间件来测试。在Startup.cs文件的Configure方法中定义:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
     if (env.IsDevelopment())
     {
         app.UseDeveloperExceptionPage();
     }

     app.UseMvc();

     app.Use(async (context, next) =>
     {
         // Forward to the next one.
         await next.Invoke();
     });
}

问题

当我通过 Postman 调用控制器时,对 POST 方法的初始调用成功通过中间件,然后到达控制器。但是,以下调用直接转到 Controller,完全跳过了中间件。这是为什么呢?

【问题讨论】:

  • 你可以使用 app.Run 代替 app.Use
  • @Progressive 与app.Use相反,app.Run不允许调用管道中的其他中间件:(

标签: c# asp.net-core middleware


【解决方案1】:

在调用app.UseMvc()之前必须设置中间件。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
     if (env.IsDevelopment())
     {
         app.UseDeveloperExceptionPage();
     }

     app.Use(async (context, next) =>
     {
         // Forward to the next one.
         await next.Invoke();
     });

     // !! Have to be called after setting up middleware !!
     app.UseMvc();
}

此信息存在于 documentation 中,但我不知道它也适用于自定义中间件:

中间件组件的添加顺序 Startup.Configure 方法定义了中间件的顺序 组件在请求和相反的顺序被调用 回复。该顺序对于安全性、性能和 功能。

下面的 Startup.Configure 方法为 常见应用场景:

1 - 异常/错误处理

2 - HTTP 严格传输安全协议

3 - HTTPS 重定向

4 - 静态文件服务器

5 - Cookie 政策实施

6 - 身份验证

7 - 会话

8 - MVC

更新

在 ASP.Net Core 3.0 中,你需要在MapControllers()之前添加你的中间件

 app.UseEndpoints(endpoints =>
 {
     endpoints.MapControllers();
 });

【讨论】:

  • 这有点令人惊讶。是否所有 MVC 框架都有这个限制,或者这是特定于 asp.net 核心的东西?
  • 3.1 的更新确实有帮助
【解决方案2】:

Startup.Configure() 在应用启动时执行一次。它用于为应用程序做准备,它不是在每次调用时都执行的。但是,您可以使用它来设置每次调用都会执行的中间件。 microsoft documentation for asp.net core application startup 包含 ConfigureConfigureServices 的一些示例。

【讨论】:

  • 我不确定你是否理解了这个问题。我知道 Configure() 被调用一次,中间件的设置也是如此。但是我认为中间件应该在每个请求时执行,就像文档中指定的那样......我已经编辑了这个问题,希望让事情更清楚。
  • 我创建了一个新的测试项目(ASP.Net Core 2.1,VS 2017 15.8.5),将你的空中间件粘贴到 Configure() 方法中,并使用中间件 IIS express 对其进行测试每次都被调用。我向默认索引页面添加了一个表单,一个发布操作,它只是将索引重定向到控制器中,并且在按下发布按钮时,每次都会再次调用中间件。然后我将控制器返回值更改为 Ok() 并再次测试,每次重新加载索引页面并按下按钮后都会再次执行中间件。
  • 我创建了一个类似的测试(ASP.NET Core 2.1 和 VS15.8.3),只有第一个调用是通过中间件...我只是不明白。
  • 我找到了。在移动东西时,我最终将 UseMvc 放在了 Configure 方法的末尾,而将中间件设置留在了之前。它现在有效。就像罗斯·盖勒在《老友记》中所说的那样,“好吧,他们应该把它写成黑色的拥抱!”
猜你喜欢
  • 2022-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多