ASP.NET Core Middleware передача параметров контроллерам

Я использую ASP.NET Core Web API, где у меня есть несколько независимых проектов web api. Перед выполнением любого из действий контроллеров я должен проверить, является ли зарегистрированный пользователь уже олицетворяющим другого пользователя (который я могу получить из БД) и может передать олицетворенный идентификатор пользователя в действия.

поскольку это фрагмент кода, который будет использоваться повторно, я подумал, что могу использовать промежуточное ПО так:

  • Я могу получить начальный логин пользователя из запроса заголовок
  • получить impesonated 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);
    }
}

Я нашел это вопрос, но это не относится к тому, что я ищу.

Как передать параметр и сделать его доступным в конвейере запросов? Можно ли передать его в заголовке или есть более элегантный способ сделать это?

2 ответов


вы можете использовать HttpContext.Элементы для передачи произвольных значений внутри конвейера:

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

лучшим решением было бы использование уровня обслуживания. Взгляните на это: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/?tabs=aspnetcore2x#per-request-dependencies

ваш код должен выглядеть так:

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);
    }
}

а затем зарегистрируйте свой ImpersonatorRepo как:

services.AddScoped<IImpersonatorRepo, ImpersonatorRepo>()