Luca Natali
Luca Natali

Reputation: 358

Adding custom headers in .NET WebAPI 2 hosted by IIS 8.5

I wrote a WEBAPI application with C# that works fine while developing but when in production, hosted by IIS 8.5 I got a problem.

In order to enable CORS (Cross Origin Resource Sharing) in my controller, I implemented the OPTION action:

[HttpOptions]
[AllowAnonymous]
public HttpResponseMessage Options()
{
    HttpResponseMessage res = new HttpResponseMessage();

    res.Headers.Add("Access-Control-Allow-Headers", "User-Agent, Content-Type, Accept, X-ApplicationId, Authorization, Host, Content-Length");
    res.Headers.Add("Access-Control-Allow-Methods", "POST");
    res.Headers.Add("Access-Control-Allow-Origin", "*");
    res.StatusCode = HttpStatusCode.OK;
    return res;
}

As I wrote before everything works ok on Visual Studio but in production, when I make an OPTIONS request using Fiddler, the answer is always:

HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/8.5
Public: OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By: ASP.NET
Date: Fri, 05 Feb 2016 16:56:20 GMT
Content-Length: 0
Proxy-Connection: keep-alive

I know that is possible to add Header's key statically in IIS but, in my controller, I need to add a Custome Header with dynamic values like that:

res.Headers.Add("X-App-Limit-Remaining", getRemainingCalls());

Anybody knows how to overwrite/change HTTP headers from a C# WEB API hosted by IIS 8. ?

Many Thanks,

Luke

Upvotes: 0

Views: 1688

Answers (1)

Nkosi
Nkosi

Reputation: 247183

You can tap into the request pipeline by using a System.Net.Http.DelegatingHandler

Reference: HTTP Message Handlers in ASP.NET Web API

You can add custom handlers to the pipeline. Message handlers are good for cross-cutting concerns that operate at the level of HTTP messages (rather than controller actions). For example, a message handler might:

  • Read or modify request headers.
  • Add a response header to responses.
  • Validate requests before they reach the controller.

Using your rate limit example here is a simplified handler:

public class WebApiRateLimitHandler : DelegatingHandler {

    //Override the SendAsync Method to tap into request pipeline
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) {
        Debug.WriteLine("Process request");
        // Call the inner handler.
        Task<HttpResponseMessage> response = base.SendAsync(request, cancellationToken);
        Debug.WriteLine("Process response");
        return response.ContinueWith(task => {
            var httpResponse = task.Result;
            httpResponse.Headers.Add("X-App-Limit-Remaining", getRemainingCalls());
            return httpResponse;
        });        
    }
}

Adding a Handler to the Pipeline

Message handlers are called in the same order that they appear in MessageHandlers collection. Because they are nested, the response message travels in the other direction. That is, the last handler is the first to get the response message.

public static class WebApiConfig {
    public static void Register(HttpConfiguration config) {
        //Order handlers are added is important. First in last out
        config.MessageHandlers.Add(new WebApiRateLimitHandler());
        config.MessageHandlers.Add(new SomeOtherMessageHandler());

        // Other code not shown...
    }
}

There is also an X-HTTP-Method-Override example. Checkout the referenced link for more examples.

Upvotes: 1

Related Questions