C# 中间件应该总是调用下一个?

C# 中间件应该总是调用下一个?,c#,owin,asp.net-core,C#,Owin,Asp.net Core,我一直在试图了解ASP.NET5管道中间件是如何工作的。据我所知,中间件只是一个Func,它是指向一个方法的指针,该方法接收对下一个请求委托的引用,并返回一个新的方法来包装下一个请求委托。当然,我们可以使用类来表示中间件,例如: public class MyMiddleware { private readonly _next; public MyMiddleware(RequestDelegate next) { if (next == null)

我一直在试图了解ASP.NET5管道中间件是如何工作的。据我所知,中间件只是一个
Func
,它是指向一个方法的指针,该方法接收对下一个请求委托的引用,并返回一个新的方法来包装下一个请求委托。当然,我们可以使用类来表示中间件,例如:

public class MyMiddleware
{
    private readonly _next;

    public MyMiddleware(RequestDelegate next)
    {
        if (next == null)
        {
            throw new ArgumentNullException("next");
        }

        _next = next;
    }

    public Task Invoke(HttpContext context)
    {
        // New request delegate code here which can wrap the next one on the pipeline
    }
}
由于
RequestDelegate
是一个委托,它可以保存对方法的引用,这些方法接收一个
HttpContext
并返回一个
Task
Invoke
方法是要返回的请求委托,并且可以访问管道上的下一个委托

在编写中间件时,我们可以访问管道的下一个组件,但我对此表示怀疑。起初,我认为理想的工作方式是:

  • 检查中间件是否可以处理请求
  • 如果可以,可以使用
    HttpContext
  • 调用管道上的下一个中间件
因此,当我第一次研究这个问题时,我认为每个中间件都应该调用下一个中间件。但这样做会导致上一节讨论的奇怪行为

同时查看一些中间件的源代码,我发现其中一些遵循另一个步骤:

  • 检查中间件是否可以处理请求
  • 如果可以的话,可以使用
    HttpContext
    执行所有必须执行的操作,仅此而已
  • 如果没有,请呼叫下一个
这是使用中间件的真实想法吗?在这种情况下,哪种方法是正确的?每个中间件都执行必须对请求执行的操作,并始终调用下一个中间件,或者如果中间件可以处理该请求,则不再调用下一个中间件


我认为中间件只有在不能处理请求时才应该调用next。我认为这是因为如果不是这样,管道上的中间件之间会存在耦合。因此,为了处理请求,中间件需要知道前一个中间件做了什么,以避免弄乱一切。这个结论正确吗?

中间件的存在使请求管道模块化,这意味着只要遵守合同,您就可以从中添加/删除/更换部件。例如,如果您的应用程序在没有任何缓存的情况下为某些文件提供服务,那么您可以在管道前端添加一个中间件,而无需更改其余部分。它们是积木

中间件可以:

  • 不执行任何操作并进一步传递请求(例如,仅适用于POST请求但当前请求为GET的中间件)
  • 不对请求执行任何操作,而是执行其他操作并进一步传递它(例如日志记录)
  • 对请求执行某些操作并进一步传递请求(例如,获取身份验证令牌并将其转换为身份,或从请求中删除一些敏感信息)
  • 结束管道,不再进一步传递请求(例如,当路由匹配时,仅返回文件或MVC)
  • 可能也回答了您的问题:有两种类型的中间件:

  • 设计用于做某事并进一步传递数据的中间件(如身份验证、cookie、验证、日志记录等)
  • 完成管道的中间件(静态文件、MVC等)
  • 当然,有些人可能会根据上下文同时做这两件事。例如,如果凭据不正确,则auth可以结束管道,否则继续

    中间件的作者必须决定是否调用下一个中间件(如果有)。对于问题中返回消息的中间件,它不应该调用下一个消息