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

标签 c# owin asp.net-core

我一直在努力了解 ASP.NET 5 管道中间件的真正工作原理。据我所知,中间件只是一个 Func<RequestDelegate, RequestDelegate> ,它是一个指向方法的指针,该方法接收对下一个请求委托(delegate)的引用并返回一个包装下一个请求委托(delegate)的新委托(delegate)。我们当然可以使用类来表示中间件,例如:

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是一个委托(delegate),可以保存对接收一个 HttpContext 的方法的引用并返回 Task Invoke方法是要返回的请求委托(delegate),它可以访问管道中的下一个委托(delegate)。

然后,在编写中间件时,我们可以访问管道的下一个组件,但我有疑问。一开始我认为理想的工作方式总是如下:

  • 检查中间件是否可以处理请求
  • 如果可以,用 HttpContext 做任何必须做的事
  • 调用管道中的下一个中间件

所以当我第一次研究这个时,我认为每个中间件应该总是调用下一个。但是这样做会导致奇怪的行为,如 this question 中所讨论的那样。 .

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

  • 检查中间件是否可以处理请求
  • 如果可以,用 HttpContext 做任何必须做的事就这样
  • 如果没有,只有在没有时才调用下一个

这就是使用中间件的真正想法吗?哪种方法是正确的方法?每个中间件执行必须对请求完成的操作并始终调用下一个,或者如果中间件可以处理请求它不再调用下一个?

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

最佳答案

中间件的存在是为了使请求管道模块化,这意味着只要您遵守契约(Contract),您就可以从中添加/删除/替换部件。例如,如果您的应用程序提供一些没有任何缓存的文件,您可以在管道的前端添加一个中间件而不改变其余部分。它们是积木。

中间件可以:

  1. 什么也不做,进一步传递请求(例如,只适用于 POST 请求但当前请求是 GET 的中间件)
  2. 什么都不请求,而是做其他事情并进一步传递它(例如日志记录)
  3. 对请求做一些事情并进一步传递请求(例如获取身份验证 token 并将其转换为身份,或从请求中删除一些敏感信息)
  4. 结束管道并且不进一步传递请求(例如 StaticFileMiddleware 只返回文件,或者在路由匹配时返回 MVC)

可能会回答您的 other question too:有两种类型的中间件:

  1. 旨在执行某些操作并进一步传递数据(例如身份验证、cookie、验证、日志记录等)的中间件
  2. 完成管道的中间件(静态文件、MVC 等)。

当然,有些人可能会根据上下文同时执行这两种操作。例如,如果凭据不正确,auth 可以结束管道,否则继续。

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

关于c# - 一个中间件应该总是调用下一个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28789305/

相关文章:

c# - SignalR 2.0.2 和 Owin 2.0.0 依赖冲突

c# - 如何使用刷新 token 更新访问 token ?

c# - ASP.NET WEB API 启动类

c# - 是否有任何约定或内置概念如何注入(inject) Json 序列化程序?

asp.net-core - System.TypeLoadException 无法加载类型 'Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions'

c# - 在 dotnet highchart 中设置图表大小?

c# - 将列添加到数据表数据类型 nvarchar

c# - 如何循环遍历所有目录中的所有文件并仅获取文件的类型?

c# - 将图像和文本保存为一个

azure - 如何使用 Linux 操作系统修复 Azure 应用服务中的问题 "IOException: Read-only file system"ASP.NET Core?