0

I am using the new MVC4 ASP.Net Web API system.

I am calling my API in a test project using WebClient. If I use GET or POST, it works fine. If I use anything else, I get Method Not Allowed. I am actually "faking" the method by injecting the following header. I am doing this because my end users will also have to do this due to the limitations of some firewalls.

I am calling the URL via IIS (i.e. not cassini) - e.g. http://localhost/MyAPI/api/Test

wc.Headers.Add("X-HTTP-Method", "PUT");

I tried adjusting the script mappings in IIS, but as there is no extension, I don't know what I am meant to be adjusting!

Any ideas? Regards Nick

3
  • How did you define your methods in your controller? Showing this in your question will help provide an answer. Did you use the attribute [HttpPut] on the method(s)? Commented Apr 30, 2012 at 12:39
  • I did exactly that - [HttpPut] Commented Apr 30, 2012 at 12:51
  • Actually, I have realised that it's causd by the X-HTTP-Method header. If I use WebRequest and set my "Method" to "PUT", it works fine. So now I'm more confused! Commented Apr 30, 2012 at 12:57

1 Answer 1

7

The X-HTTP-Method (or X-HTTP-Method-Override) header is not supported out of the box by Web API. You will need to create a custom DelegatingHandler (below implementation assumes that you are making your request with POST method as it should be):

public class XHttpMethodDelegatingHandler : DelegatingHandler
{
    private static readonly string[] _allowedHttpMethods = { "PUT", "DELETE" };
    private static readonly string _httpMethodHeader = "X-HTTP-Method";

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Method == HttpMethod.Post && request.Headers.Contains(_httpMethodHeader))
        {
            string httpMethod = request.Headers.GetValues(_httpMethodHeader).FirstOrDefault();
            if (_allowedHttpMethods.Contains(httpMethod, StringComparer.InvariantCultureIgnoreCase))
            request.Method = new HttpMethod(httpMethod);
        }
        return base.SendAsync(request, cancellationToken);
    }
}

Now you just need to register your DelegatingHandler in Global.asax:

protected void Application_Start(object sender, EventArgs e)
{
    GlobalConfiguration.Configuration.MessageHandlers.Add(new XHttpMethodDelegatingHandler());
    ...
}

This should do the trick.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.