web-dev-qa-db-fra.com

Middleware ASP.NET Core, transmission des paramètres aux contrôleurs

J'utilise ASP.NET Core Web API, où j'ai plusieurs projets d'API Web indépendants. Avant d'exécuter l'une des actions des contrôleurs, je dois vérifier si l'utilisateur connecté emprunte déjà l'identité d'un autre utilisateur (que je peux obtenir de DB) et peut transmettre l'utilisateur emprunté Id à le actions.

Puisque c'est un morceau de code qui va être réutilisé, je pensais pouvoir utiliser un middleware donc:

  • Je peux obtenir la connexion initiale de l'utilisateur à partir de l'en-tête de la demande
  • Obtenez l'ID utilisateur impesoné le cas échéant
  • Injectez cet ID dans le pipeline de demande pour le rendre disponible à l'api appelée
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);
    }
}

J'ai trouvé cela Question , mais cela ne répond pas à ce que je recherche.

Comment passer un paramètre et le rendre disponible dans le pipeline de demande? Est-ce Ok pour le passer dans l'en-tête ou il existe une façon plus élégante de le faire?

17
Hussein Salman

Vous pouvez utiliser HttpContext.Items pour passer des valeurs arbitraires à l'intérieur du pipeline:

context.Items["some"] = "value";
12
Ricardo Peres

Une meilleure solution serait d'utiliser un service de portée. Jetez un œil à ceci: https://docs.Microsoft.com/en-us/aspnet/core/fundamentals/middleware/?tabs=aspnetcore2x#per-request-dependencies

Votre code devrait ressembler à:

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

Et puis enregistrez votre ImpersonatorRepo en tant que:

services.AddScoped<IImpersonatorRepo, ImpersonatorRepo>()
7
Motumbo