Tunneling PUT, DELETE and HEAD methods as POSTs

Applies to: Asp.net MVC WebAPI projects

This post is adapted from Hanselman.

Step 1. Add the following MethodOverrideHandler.cs class in the project root:

    public class MethodOverrideHandler : DelegatingHandler
    {
        readonly string[] _methods = { "DELETE", "HEAD", "PUT" };
        const string _header = "X-HTTP-Method-Override";

        protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // Check for HTTP POST with the X-HTTP-Method-Override header.
            if (request.Method == HttpMethod.Post && request.Headers.Contains(_header))
            {
                // Check if the header value is in our methods list.
                var method = request.Headers.GetValues(_header).FirstOrDefault();
                if (_methods.Contains(method, StringComparer.InvariantCultureIgnoreCase))
                {
                    // Change the request method.
                    request.Method = new HttpMethod(method);
                }
            }
            return base.SendAsync(request, cancellationToken);
        }
    }

 

Step 2. In the Register method of App_Start/WebApiConfig.cs, insert the following code:

 

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

 

Step 3. You’ll need to modify any client calls of PUT, DELETE or HEAD that access your WebApi project. For each affected call, add the following header:

'X-HTTP-Method-Override': 'PUT'

or
'X-HTTP-Method-Override': 'DELETE'

or
'X-HTTP-Method-Override': 'HEAD'

…and then make your AJAX call as a POST, adding whatever parameters you need either as part of the URL or as data.

Now your PUT, DELETE or HEAD calls will pass through the firewall as POSTs, be recognized by a message handler for what they truly are and converted to their native method, then passed to your Controllers to be executed as expected.