3
votes

I am putting together a talk for a local Code Camp and am trying to understand the nuances of HTTP Verbs in ApiController. Several things about ApiController significantly changed between Beta, RC and final release, and the advice on how you can set this up is conflicting and sometimes wrong.

Assuming I am just leaving the standard routing in WebApiConfig:

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }

(since you can really put things on their head if you add in an {action} parameter here)

I understand how the convention is working for simple Crud calls like:

    // GET api/values
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }


    // GET api/values/5
    public string Get(int id)
    {
        return "value";
    }

    // POST api/values
    public void Post([FromBody]string value)
    {
    }

Or that you can change these as long as they start with the verb name:

    // GET api/values/5
    public string GetMyStuff(int id)
    {
        return "value";
    }

However, the initial spec says that ApiController supports Get, Put, Post and Delete. Yet I can add methods for:

    public void HeadOfTheClass()
    {
    }

Which works for a Head verb, but I can’t add methods for the obscure or non-existent verbs:

    public void MKCOL()
    {
    }
    public void Bubba()
    {
    }

What is the full list of Native “Supported” verbs?

I can however add support for these methods by using the AcceptVerb attribute:

    [AcceptVerbs("MKCOL")] 
    public void MKCOL()
    {
    }
    [AcceptVerbs("Bubba")]
    public void Bubba()
    {
    }

This also works, or for any “defined” verb use the Http attributes:

    [HttpHead]
    public void HeadOfTheClass()
    {
    }

   [HttpGet]
    public void Bubba()
    {
    }

Which is correct or preferred? (There was also attributes like [GET] and [POST] as well, are these deprecated?)

Are [HttpBindNever] and [NonAction] equivalent?

1
At SO it is best to ask only one question at a time. I answered what seemed the main question. It is probably best if you edit this question and create 2 or 3 individual questions from it.ScottS

1 Answers

8
votes

I love open source. :)

From ReflectedHttpActionDescriptor:

private static readonly HttpMethod[] _supportedHttpMethodsByConvention = 
    { 
        HttpMethod.Get, 
        HttpMethod.Post, 
        HttpMethod.Put, 
        HttpMethod.Delete, 
        HttpMethod.Head, 
        HttpMethod.Options, 
        new HttpMethod("PATCH") 
    };