ASP.NET Core中间件向控制器传递参数

28

我正在使用 ASP.NET Core Web API,其中有多个独立的 Web API 项目。在执行任何控制器操作之前,我必须检查已登录的用户是否已模拟其他用户(可以从DB中获取),并且可以将模拟用户ID传递给actions

由于这是一段将要被重复使用的代码,我想使用中间件,以便:

  • 我可以从请求头中获取初始用户登录
  • 如果有,则获取模拟用户ID
  • 将该ID注入请求管道中,使其可用于调用的API。
public class GetImpersonatorMiddleware
{
    private readonly RequestDelegate _next;
    private IImpersonatorRepo _repo { get; set; }

    public GetImpersonatorMiddleware(RequestDelegate next, IImpersonatorRepo imperRepo)
    {
        _next = next;
        _repo = imperRepo;
    }
    public async Task Invoke(HttpContext context)
    {
        //get user id from identity Token
        var userId = 1;

        int impersonatedUserID = _repo.GetImpesonator(userId);

        //how to pass the impersonatedUserID so it can be picked up from controllers
        if (impersonatedUserID > 0 )
            context.Request.Headers.Add("impers_id", impersonatedUserID.ToString());

        await _next.Invoke(context);
    }
}

我找到了这个问题,但那并没有解决我正在寻找的。

我应该如何传递参数并使其在请求管道中可用?将其放在标头中可以吗,还是有更优雅的方法来处理这个问题?


你应该更改请求上下文,而不是管道本身。 - Lex Li
@LexLi,您能否举个例子详细说明一下?您是指将一些信息添加到请求本身并从控制器中获取吗?如果是这样,我也在考虑这个问题,但是再次问一下,在哪里添加,查询字符串、正文,这不会影响调用的操作吗? - Hussein Salman
2个回答

30

您可以使用HttpContext.Items在管道内传递任意值:

context.Items["some"] = "value";

4
另请参阅:使用HttpContext.Items - poke
我正在使用Session。context.Session.SetInt32("user-id", 12345); 哪种方法最好,为什么? - Muhammad Saqib
会话可能已启用,也可能未启用,并且会话需要cookies。 - Ricardo Peres
1
这似乎仍然是在中间件管道外存储值的唯一有效解决方案。 - Sven

16

更好的解决方案是使用作用域服务。看一下这个链接:每个请求的中间件依赖

你的代码应该像这样:

public class MyMiddleware
{
    private readonly RequestDelegate _next;

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

    public async Task Invoke(HttpContext httpContext, IImpersonatorRepo imperRepo)
    {
        imperRepo.MyProperty = 1000;
        await _next(httpContext);
    }
}

然后将您的模仿者存储库注册为:

services.AddScoped<IImpersonatorRepo, ImpersonatorRepo>()

3
在中间件之外,每次请求使用服务时会发生错误。请参阅 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-3.1#per-request-middleware-dependencies 。为了使其工作,请在中间件内部使用服务。 - Sven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接