How to assign multiple MVC routes to one method and determine the used route?

174 views Asked by At

I have the following code:

public IActionResult Up(int id)
{
    return Move(id, "up");
}

private IActionResult Move(int id, string action)
{
    // Do something based on the action
    switch (action)
    {
        case "up":
            break;
        case "down":
            break;
    }
}

This works fine and is easy to maintain. But now I've thought that I could refactor the code by combining the methods:

[Route("item/up/{id}")]
[Route("item/down/{id}")]
public IActionResult Move([FromRoute]string action, [FromRoute]int id)
{
}

The link /item/up/155 will hit this method while the link /item/up2/155 returns NotFound, as expected.

The problem now is, that when I check the value of action, then it does not contain the value up, but the value Move.

This seems odd as the controller name is not transformed into ItemController. So one could argue that the value should be up. But assuming this is the design and won't change, then how can I find the actual value?

I can parse Request.Path.Value (="/item/up/155"), but I'd prefer not to as I would like to keep things simple.

So I am looking for an easy way to assign multiple routes to one method and then determine what the value of the action parameter in the used route path was.

1

There are 1 answers

2
Thangadurai On

Instead of hard coding the direction as 'up' and 'down' in the route declaration, you can treat that as a parameter. Since you used the keyword 'action' as a parameter, during the parameter binding the actual action method selected by the framework will be assigned to it.

You can try the following code -

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    [Route("item/{direction}/{id}")]
    public string Move([FromRoute]string controller, [FromRoute]string action, string direction, string id)
    {
        return string.Format("Controller={0} Action={1} Direction={2} Id={3}", controller, action, direction, id);
    }
}