David Ruttka

I make computers do things

Where Did Attribute Routing Go When Updating From Web API 5.0.0 Pre to Web API 2?

This is just a heads up for moving to Web API 2 from the prerelease bits. If you weren’t using Web API 5.0.0-pre bits, you can probably ignore this and never know any different. I’m not going to cover Attribute Routing itself here – plenty of posts have already done that.

tl;dr – instead of HttpGet(“route”), you now use Route(“route”), and optionally use HttpGet with no arguments if you need to explicitly define the HTTP method. Same goes for HttpPost, etc.

I updated a project from the Web API prerelease to the official Web API 2 a few nights ago, and it broke my build. The HttpGet and HttpPost attributes take no arguments, so [HttpGet(“someroute”)] and [HttpPost(“otherRoute”)] were no longer valid.

Now, you just use [Route(“theRoute”)], and it will take it’s best guess about which HTTP Method to use. It’s usually right (especially if you use the preexisting conventions). I felt the need to find a contrived example where it chooses wrong to confirm how to make it right.

Let’s say we want this X to get wired up as GET /api. It actually gets wired as a POST, and if you try to GET, it throws 405 Method Not Allowed.

1
2
3
4
5
6
7
8
9
[RoutePrefix("api")]
public class ValuesController : ApiController
{
  [Route("")]
  public int X()
  {
    return 42;
  }
}

In reality, I’d just rename this from X to Get, but this is a contrived example! Let’s pretend someone put a note on the work item that the implementation method must be named X. We can turn the world right-side-up again by stacking the Http* method attribute. The following works as GET /api, and attempting to POST throws 405.

1
2
3
4
5
6
7
8
9
10
[RoutePrefix("api")]
public class ValuesController : ApiController
{
  [Route("")]
  [HttpGet]
  public int X()
  {
    return 42;
  }
}

Hope this saves someone a few minutes sometime.

This post originally appeared on The DevStop.