C#dotnet core 2将数据从中间件/过滤器传递到控制器方法

时间:2017-10-06 08:42:59

标签: c# .net-core asp.net-core-2.0

目前我们正在编写一个带有dotnet core 2的Web应用程序。

我们实际上创建了一种多主机平台,我们可以根据传递给我们应用程序的URL注册新客户端。

但是目前我们想要创建一个中间件/过滤器来验证我们的客户端。

实际上我们想要做的是从数据库中提取一个对象并检查它是否存在,如果是,我们要调用控制器方法并使对象可访问,如果它不存在,我们实际上想要中止和显示错误页面。

我们已经完成的工作是创建一个完全相同的过滤器/中间件,但是我们无法找到一种方法来访问我们已经在控制器方法中的过滤器/中间件中提取的对象。

实际上有没有这方面的文件?

我实际上试图弄明白: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware?tabs=aspnetcore2x https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/filters

但他们没有描述一种方法,只是在行动之前/之后实际做某事。

2 个答案:

答案 0 :(得分:12)

您可以使用文档声明的HttpContext.Items将对象添加到上下文中:

  

Items集合是存储仅在处理一个特定请求时所需的数据的好位置。每次请求后都会丢弃集合的内容。 Items集合最适合用作组件或中间件在请求期间在不同时间点操作时进行通信的方式,并且无法直接传递参数。

例如,在您的中间件中:

public class MySuperAmazingMiddleware
{
    private readonly RequestDelegate _next;

    public MySuperAmazingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext context)
    {
        var mySuperAmazingObject = GetSuperAmazingObject();

        context.Items.Add("SuperAmazingObject", mySuperAmazingObject );

        // Call the next delegate/middleware in the pipeline
        return this._next(context);
    }
}

然后在您的操作方法中,您可以读取值:

var mySuperAmazingObject = (SuperAmazingObject)HttpContext.Items["mySuperAmazingObject"];

答案 1 :(得分:3)

这样做的一种方式(不是说它是唯一的或最好的)是让DI注入对象的代理,你在中间件中设置对象的实际值,然后你可以从代理中访问它控制器。

注意:如果您将在方法调用而不是控制器中传递代理对象,请不要忘记使用[FromServices]属性进行标记。

另一种方法是将对象添加到请求Items属性中。但是当你阅读它时,你需要从object到你真正的班级。