Search code examples
c#asp.net-web-apiasp.net-web-api-routing

Routing for executing different GET methods with same type of parameter


Could anybody little help me with routing?

In WebApiConfig I have this mapping

config.Routes.MapHttpRoute(DefaultApi",
    routeTemplate: "{controller}/{uid}",
    defaults: new {uid = RouteParameter.Optional}
);

and two methods in controller

[RoutePrefix("AppartmentCategory")]
public class AppartmentCategoryController : ApiController
{
    [HttpGet]
    public IHttpActionResult Get(Guid uid){...}

    [HttpGet]
    [Route("{propertyUid?}")]
    public IHttpActionResult GetList(Guid propertyUid){...}
}

When I try to send requests

1. http://.../AppartmentCategory/043F61D1-7194-E611-A98B-9C5C8E0005FA

and

2. http://.../AppartmentCategory/?propertyUid=2fdc968d-0192-e611-a98b-9c5c8e0005fa

In both cases executing method public IHttpActionResult GetList(Guid propertyUid)

What shold I fix for executing public IHttpActionResult Get(Guid uid) method for first request?


Solution

  • You are mixing convention-based routing and attribute routing. config.MapHttpAttributeRoutes() is mapped before convention-based routes (as it should)

    config.MapHttpAttributeRoutes();
    
    config.Routes.MapHttpRoute(DefaultApi",
        routeTemplate: "{controller}/{uid}",
        defaults: new {uid = RouteParameter.Optional}
    );
    

    so it will hit the GetLists first as first match always win when matching templates. Technically both actions will have similar routes.

    [RoutePrefix("AppartmentCategory")]
    public class AppartmentCategoryController : ApiController
    {
        //GET AppartmentCategory/043F61D1-7194-E611-A98B-9C5C8E0005FA VIA CONVENTION-BASED ROUTING
        [HttpGet]
        public IHttpActionResult Get(Guid uid){...}
    
        //GET AppartmentCategory/2fdc968d-0192-e611-a98b-9c5c8e0005fa VIA ATTRIBUTE ROUTING    
        [HttpGet]
        [Route("{propertyUid?}")]
        public IHttpActionResult GetList(Guid propertyUid){...}
    }
    

    You should try to differentiate the two actions a little more and also try not to mix convention-based and attribute routing in the same controller.

    [RoutePrefix("AppartmentCategory")]
    public class AppartmentCategoryController : ApiController {
        //GET AppartmentCategory/043F61D1-7194-E611-A98B-9C5C8E0005FA
        [HttpGet]
        [Route("{uid:guid}")]
        public IHttpActionResult Get(Guid uid){...}
    
        //GET AppartmentCategory?propertyUid=2fdc968d-0192-e611-a98b-9c5c8e0005fa
        [HttpGet]
        [Route("")]
        public IHttpActionResult GetList(Guid propertyUid){...}
    }