28

I want to create a new Handler that extends DelegatingHandler to enable me to do stuff before getting as far as the controller. I have read in various places that I need need to inherit from DelegatingHandler then overrride SendAsync() like this:

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

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

This is all fine and dandy except it doesn't do anything because I haven't registered it anywhere! Again, I have seen in numerous places that I should do so in WebApiConfig.cs but that is not a part of the ASP.NET Core version of Web API. I have tried to find analogues amoungst the various things in the Startup.cs file (Configure(), ConfigureServices() etc) but no luck.

Can anyone please tell me how I should go about registering my new handler?

Nkosi
  • 191,971
  • 29
  • 311
  • 378
Ben
  • 4,915
  • 7
  • 40
  • 57
  • 1
    They are gone now, see [this article](http://www.dotnetcurry.com/aspnet-mvc/1149/convert-aspnet-webapi2-aspnet5-mvc6) for example. Suggestion is to write OWIN middleware instead – Andrei Nov 02 '16 at 17:18
  • As already mentioned in previous comment, look into [Writing middleware](https://docs.asp.net/en/latest/fundamentals/middleware.html#writing-middleware) – Nkosi Nov 02 '16 at 17:56

1 Answers1

23

As already mentioned in previous comment, look into Writing your own middleware

Your ApiKeyHandler can be converted into a middleware class that takes in the next RequestDelegate in its constructor and supports an Invoke method as shown:

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

Middleware can take advantage of the UseMiddleware<T> extension to inject services directly into their constructors, as shown in the example below. Dependency injected services are automatically filled, and the extension takes a params array of arguments to be used for non-injected parameters.

ApiKeyExtensions.cs

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

Using the extension method and associated middleware class, the Configure method becomes very simple and readable.

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

    app.UseApiKey();

    //...other configuration
}
killa-byte
  • 511
  • 5
  • 15
Nkosi
  • 191,971
  • 29
  • 311
  • 378