web-dev-qa-db-fra.com

Enregistrement d'un nouveau DelegatingHandler dans l'API Web ASP.NET Core

Je veux créer un nouveau gestionnaire qui étend DelegatingHandler pour me permettre de faire des choses avant d'aller jusqu'au contrôleur. J'ai lu à différents endroits que j'ai besoin d'hériter de DelegatingHandler, puis écraser SendAsync () comme ceci:

public class ApiKeyHandler : DelegatingHandler
{        
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {          
        // do custom stuff here

        return base.SendAsync(request, cancellationToken);
    }
}

C'est très bien et dandy sauf qu'il ne fait rien parce que je ne l'ai enregistré nulle part! Encore une fois, j'ai vu à de nombreux endroits que je devrais le faire dans WebApiConfig.cs mais cela ne fait pas partie de la version ASP.NET Core de l'API Web. J'ai essayé de trouver des analogues parmi les différentes choses dans le fichier Startup.cs (Configure (), ConfigureServices () etc.) mais pas de chance.

Quelqu'un peut-il me dire comment procéder pour enregistrer mon nouveau gestionnaire?

23
Ben

Comme déjà mentionné dans le commentaire précédent, examinez Écriture de votre propre middleware

Votre ApiKeyHandler peut être converti en une classe middleware qui prend la prochaine RequestDelegate dans son constructeur et prend en charge une méthode Invoke comme indiqué:

using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace MyMiddlewareNamespace {

    public class ApiKeyMiddleware {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;
        private IApiKeyService _service;

        public ApiKeyMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IApiKeyService service) {
            _next = next;
            _logger = loggerFactory.CreateLogger<ApiKeyMiddleware>();
            _service = service
        }

        public async Task Invoke(HttpContext context) {
            _logger.LogInformation("Handling API key for: " + context.Request.Path);

            // do custom stuff here with service      

            await _next.Invoke(context);

            _logger.LogInformation("Finished handling api key.");
        }
    }
}

Le middleware peut tirer parti de UseMiddleware<T> extension pour injecter des services directement dans leurs constructeurs, comme illustré dans l'exemple ci-dessous. Les services injectés par dépendance sont automatiquement remplis et l'extension prend un tableau params d'arguments à utiliser pour les paramètres non injectés.

ApiKeyExtensions.cs

public static class ApiKeyExtensions {
    public static IApplicationBuilder UseApiKey(this IApplicationBuilder builder) {
        return builder.UseMiddleware<ApiKeyMiddleware>();
    }
}

En utilisant la méthode d'extension et la classe middleware associée, la méthode Configure devient très simple et lisible.

public void Configure(IApplicationBuilder app) {
    //...other configuration

    app.UseApiKey();

    //...other configuration
}
21
Nkosi