Регистрация нового DelegatingHandler в ASP.NET Core Web API

Я хочу создать новый обработчик, который расширяет DelegatingHandler, чтобы позволить мне делать вещи, прежде чем доходить до контроллера. Я читал в разных местах, что мне нужно наследовать от DelegatingHandler, а затем переопределить SendAsync() следующим образом:

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

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

Это все прекрасно и денди, за исключением того, что он ничего не делает, потому что я его нигде не зарегистрировал! Опять же, я видел во многих местах, что я должен делать это в WebApiConfig.cs, но это не является частью ASP.NET Core версии Web API. Я попытался найти аналоги среди различных вещей в файле Startup.cs(Configure(), ConfigureServices() и т.д.), Но не повезло.

Может кто-нибудь, пожалуйста, скажите мне, как мне нужно регистрировать моего нового обработчика?

Ответы

Ответ 1

Как уже упоминалось в предыдущем комментарии, посмотрите на " Написание собственного промежуточного программного обеспечения"

Ваш ApiKeyHandler может быть преобразован в класс промежуточного программного обеспечения, который принимает следующий RequestDelegate в своем конструкторе и поддерживает метод Invoke как показано:

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

Среднее программное обеспечение может использовать расширение UseMiddleware<T> для непосредственного использования служб в своих конструкторах, как показано в примере ниже. Зависимые инъецируемые услуги автоматически заполняются, а расширение принимает массив params параметров, который будет использоваться для неинжектированных параметров.

ApiKeyExtensions.cs

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

Используя метод расширения и связанный с ним класс промежуточного ПО, метод Configure становится очень простым и удобочитаемым.

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

    app.UseApiKey();

    //...other configuration
}