How to map WebAPI routes correctly How to map WebAPI routes correctly asp.net asp.net

How to map WebAPI routes correctly


Given the flexibility you want you should take a look at

Attribute Routing in ASP.NET Web API 2

In WebApiConfig.cs enable attribute routing like

// Web API routesconfig.MapHttpAttributeRoutes();

In UserController

Note given the names of actions Friends, Followers and Favorites they imply returning collections rather than single user

[RoutePrefix("api/users")]public class UserController: ApiController {    //eg: GET api/users?firstname={firstname}&lastname={lastname}    [HttpGet]    [Route("")]    public User Get([FromUri]string firstname,[FromUri] string lastname) {...}    //eg: GET api/users/{id}    [HttpGet]    [Route("{id:guid}")]    public User Get(Guid id){...}    //eg: GET api/users/{id}/friends    [HttpGet]    [Route("{id:guid}/friends")]    public IEnumerable<User> Friends(Guid id){...}    //eg: GET api/users/{id}/followers    [HttpGet]    [Route("{id:guid}/followers")]    public IEnumerable<User> Followers(Guid id){...}    //eg: GET api/users/{id}/favorites    [HttpGet]    [Route("{id:guid}/favorites")]    public IEnumerable<User> Favorites(Guid id){...}}


Routing is order sensitive. The first match always wins. So it is important that you order you routes from most-specific to least-specific.

// All parameters are required, or it won't match.// So it will only match URLs 4 segments in length// starting with /api.config.Routes.MapHttpRoute(     "1",     "api/{controller}/{id}/{action}");// Controller is required, id is optional.// So it will match any URL starting with// /api that is 2 or 3 segments in length.config.Routes.MapHttpRoute(    "2",    "api/{controller}/{id}",    new { action = "get", id = RouteParameter.Optional });

When your routes are ordered this way, you will get the behavior you expect.


There are a variety of useful reference materials on this subject, such as:

Have you had a look at these?

Update..

Its better practise to explicitly state which parameter is which, ie:

    config.Routes.MapHttpRoute(        name: "2",        routeTemplate: "api/{controller}/{id}",        defaults: new { action = "Get", id = RouteParameter.Optional },    );    config.Routes.MapHttpRoute(        name: "1",        routeTemplate: "api/{controller}/{action}/{id}",        defaults: null    );

Main thing I could see wrong was you had action / id in the wrong order in route "1".