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

Map two different routes to the same controller action


I am working on extending the example at: https://docs.asp.net/en/latest/tutorials/first-web-api.html

They have a ToDo apis: /api/todo and /api/todo/{id}.

I want to extend it to ToDoGroups /api/ToDoGroup.

Under ToDoGroup, I want to reach a ToDo by the follwoing: /api/ToDoGroup/{id}/ToDo/{id}.

How can I make it point to the same controller action? For example the following action below will also have another route like [HttpGet("ToDoGroup/{ToDoGroupid}/ToDo/{ToDoid}", Name = "GetTodo")]

[HttpGet("{id}", Name = "GetTodo")]
public IActionResult GetById(string id)
{
    var item = TodoItems.Find(id);
    if (item == null)
    {
        return NotFound();
    }
    return new ObjectResult(item);
}

Solution

  • first change the controller's route prefix:

          [Route("api/todogroup/{groupId:int}")]
          public class TodoController : Controller 
    

    then change your action's route:

          [HttpGet("todo/{id}", Name = "GetTodo")]
          public IActionResult GetById(int groupId, string id)
    

    edit: to get both routes, you can do this:

            [Route("api")]
          public class TodoController : Controller 
    
              [HttpGet("todo/{id}", Name = "GetTodo")]//api/todo/43
          public IActionResult GetById(string id)
    
          [HttpGet("todogroup/{groupdId:int}/todo/{id}", Name = "GetGroupTodo")]//api/todogroup/100/todo/43
          public IActionResult GetById(int groupId, string id)
    

    Asp.Net Web Api has a way of negating a route prefix (the route specified on the controller), but I cant find an equivalent in Asp.Net Core.