在ASP.NET Core Web API中注册新的DelegatingHandler

Ben*_*Ben 24 c# asp.net-web-api asp.net-core-mvc asp.net-core asp.net-core-webapi

我想创建一个新的Handler,它扩展了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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是好的和花花公子,除了它没有做任何事情,因为我没有在任何地方注册!我再次在很多地方看到我应该在WebApiConfig.cs中这样做,但这不是Web API 的ASP.NET 核心版本的一部分.我试图找到类似于Startup.cs文件(Configure(),ConfigureServices()等)中的各种东西,但没有运气.

任何人都可以告诉我如何注册我的新处理程序?

Nko*_*osi 21

正如之前的评论中已经提到的,请研究编写自己的中间件

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.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

中间件可以利用UseMiddleware<T>扩展将服务直接注入其构造函数,如下面的示例所示.自动填充依赖注入服务,扩展使用一params组参数用于非注入参数.

ApiKeyExtensions.cs

public static class ApiKeyExtensions {
    public static IApplicationBuilder UseApiKey(this IApplicationBuilder builder) {
        return builder.UseMiddleware<ApiKeyMiddleware>();
    }
}
Run Code Online (Sandbox Code Playgroud)

使用扩展方法和相关的中间件类,Configure方法变得非常简单和可读.

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

    app.UseApiKey();

    //...other configuration
}
Run Code Online (Sandbox Code Playgroud)

  • @shaikhspear 是的,这是一个公平的声明。 (2认同)