简体   繁体   中英

Custom Delegating Handler specific to a Controller in ASP.NET Web API

I have written a Custom Delegating Handler which add custom headers to the response & checks in the request .

I added the handles in WebAPi configuration

config.MessageHandlers.Add(new customHandler());

But the issue is applies to all the controllers. I need to apply custom header specific to a controllers. Is it possible to add custom handlers specific to a controller?

At the end of this article it explains how to apply handlers only to certain routes: http://www.asp.net/web-api/overview/working-with-http/http-message-handlers . You may have to create a unique handler for your controller for it to apply to that controller only.

    config.Routes.MapHttpRoute(
        name: "MyCustomHandlerRoute",
        routeTemplate: "api/MyController/{id}",
        defaults: new { controller = "MyController", id = RouteParameter.Optional },
        constraints: null,
        handler: HttpClientFactory.CreatePipeline(new HttpControllerDispatcher(config), new MyCustomDelegatingMessageHandlerA());
    );

Regarding how the pipeline of per-route message handlers would look like, you can look here .

What you can do is use the per-route message handler but be careful here. As the article that @Nick linked in his answer, you can chain the handler and ensure that the HttpControllerDispatcher is involved. Otherwise, you won't get into the Controller pipeline.

One other option which I like is to use the HttpControllerDispatcher as a base class for your custom handler:

public class CustomerOrdersDispatcher : HttpControllerDispatcher {

    public CustomerOrdersDispatcher(HttpConfiguration config) 
        : base(config) {
    }

    protected override Task<HttpResponseMessage> SendAsync(
        HttpRequestMessage request, 
        CancellationToken cancellationToken) {

        // Do some stuff here...

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

Here, how you will register it:

protected void Application_Start(object sender, EventArgs e) {

    var config = GlobalConfiguration.Configuration;

    config.Routes.MapHttpRoute(
        name: "CustomerOrdersHttpRoute",
        routeTemplate: "api/customers/{customerKey}/orders/{key}",
        defaults: new { controller = "CustomerOrders", key = RouteParameter.Optional },
        constraints: null,
        handler: new CustomerOrdersDispatcher(config)
    );

    config.MessageHandlers.Add(new SomeOtherHandler1());
    config.MessageHandlers.Add(new SomeOtherHandler2());
}

After SomeOtherHandler1 and SomeOtherHandler2 are executed, your CustomerOrdersDispatcher will be executed for CustomerOrdersHttpRoute route. So, you can see that you preserve the default handler behavior and set some global handlers while you have a route specific one as well.

Here is the full implementation of my CustomerOrdersDispatcher : https://github.com/tugberkugurlu/AdvancedWebAPI/blob/master/PerRouteMHOwnershipSample/Dispatcher/CustomerOrdersDispatcher.cs .

You may view the full sample application source code as well to see how it works out: https://github.com/tugberkugurlu/AdvancedWebAPI/tree/master/PerRouteMHOwnershipSample

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM