HTTP DELETE/PUT Not Allowed? Web API 2

I like the conventional approach of REST using GET, POST, PUT and DELETE verbs to interact with the resources. Recently i had to work with an IIS server where PUT and DELETE verbs were restricted due to security reasons. As i had done a lot of work on the project and it would be too difficult to change all the resources and end points. I had to take another route which make my resources and end points work without many modifications.

I came across the article by Scott Hanselman. An HTTP header X-HTTP-Method-Override can be sent from the client telling the server application to override the HTTP verb to the override value provided in this header.

Lets assume the Web API application is configured to use PUT and DELETE for updating and deleting the resources respectively. But at the time of hosting it is found out that these two verbs are not allowed on IIS.

Following is a request from client side to update a record of student with an id = 5. Ideally the service should use the verb PUT as its an update request on the resource. In my case web API expects a PUT verb on this route.

$.ajax({
  url: "http://localhost:50098/api/students/5",
  data: { name: "Tom", age: 10 },
    type: "POST",
    beforeSend: function (xhr)
    { xhr.setRequestHeader('X-Test-Header', 'test-value'); },
    success: function ()
    { alert('Success!' + authHeader); }
});

POST verb will make it pass through the IIS gates safely to the Web API. We will need to introduce an HTTP handler so that before the route is calculated and the control is passed to the filters and controllers, we can change the verb POST back to the expected verb PUT.

You can write your own handler, you can also find a handler in nuget e.g., XHTTPMethodOverride.

public class MethodOverrideHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
    CancellationToken cancellationToken)
    {
        if (request.Method == HttpMethod.Post &&
            request.Headers.Contains("X-HTTP-Method-Override"))
        {
            var method = request.Headers.
                         GetValues("X-HTTP-Method-Override").FirstOrDefault();
            bool isPut = String.Equals(method, "PUT",
StringComparison.OrdinalIgnoreCase);
            bool isDelete = String.Equals(method, "DELETE",
StringComparison.OrdinalIgnoreCase);
            if (isPut || isDelete)
            {
                request.Method = new HttpMethod(method);
            }
        }
        return await base.SendAsync(request, cancellationToken);
    }
}

Assuming your handler is registered with Web API configurations, the POST request having X-HTTP-Method-Override will be intercepted by the handler and request.Method = new HttpMethod(method); will override the POST verb back to the PUT or DELETE.

The handler will pass this data to the filters and controllers method and everything will start working as expected.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s