我是 .NET Core 的新手,所以如果我听起来很天真,请原谅我。
(引用:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?view=aspnetcore-3.1)
Warning
Don't call next.Invoke after the response has been sent to the client. Changes to HttpResponse after the response has started throw an exception. For example, setting headers and a status code throw an exception. Writing to the response body after calling next:
May cause a protocol violation. For example, writing more than the stated Content-Length. May corrupt the body format. For example, writing an HTML footer to a CSS file.
HasStarted is a useful hint to indicate if headers have been sent or the body has been written to.
根据上面的 Microsoft 文档,以下内容将是不好的编程实践。但是,假设我希望网页向应用程序的网页用户指示中间件组件已被执行(这意味着写入响应)
app.Use(async (context, next) => { await context.Response.WriteAsync("<div> Hello World from the middleware 1 </div>"); await next.Invoke(); }); app.Use(async (context, next) => { await context.Response.WriteAsync("<div> Hello World from the middleware 2 </div>"); await next.Invoke(); });
由于上面的 Microsoft 技术文档声明从不调用“next.Invoke 在响应发送到客户端后”,那么有人可以告诉我如何实现执行相同操作但仍然保留的代码吗?一个好的做法?
最佳答案
重点是应该只有一个中间件负责生成响应。如果多个中间件彼此联锁,则表明它应该是单个中间件。
例如,MVC 中间件本身有点像这样:使用 MVC 过滤器,有多个参与者可以产生结果。为了克服这个问题,MVC 有自己的管道,它不会直接写入响应,而是收集中间结果,仅在最后写入响应。这就是 IActionResult
抽象的作用:当过滤器运行时,它们可以修改操作结果,并且仅在 MVC 管道的末尾(以及 MVC 中间件的末尾),结果为已执行。
如果您只需要在中间件之间传输信息,那么使用响应无论如何都是一个坏主意,因为后面的中间件无法读取该信息。因此最好将信息存储在其他地方。 HttpContext 是一个很好的地方。 HttpContext.Items
是一个简单的存储,用于在您可以使用的请求期间保存信息。如需更详细的信息,您还可以使用可通过HttpContext.Features
注册的“功能”。 。例如,功能与端点路由一起使用,以允许其他中间件访问当前请求的路由信息(例如,允许授权中间件为特定端点授权用户)。有关项目和功能的更多详细信息,请查看 this question .
关于asp.net-core - .net Core **从不调用** "next.Invoke after the response has been sent to the client"那么如何实现符合良好实践的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62959681/