Как назначить несколько маршрутов MVC одному методу и определить используемый маршрут? - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть следующий код:

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;
    }
}

Это прекрасно работает и прост в обслуживании. Но теперь я подумал, что мог бы реорганизовать код, комбинируя методы:

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

Ссылка /item/up/155 будет использовать этот метод, а ссылка /item/up2/155 возвращает NotFound, как и ожидалось.

Проблема в том, что когда я проверяю значение action, тогда оно не содержит значение up, а значение Move.

Это кажется странным, поскольку имя контроллера не преобразуется в ItemController. Таким образом, можно утверждать, что значение должно быть up. Но если предположить, что это дизайн и он не изменится, то как мне найти фактическое значение?

Я могу разобрать Request.Path.Value (= "/ item / up / 155"), но я бы предпочел не делать этого, поскольку хотел бы, чтобы все было просто.

Поэтому я ищу простой способ назначить несколько маршрутов одному методу, а затем определить, какое значение параметра действия в используемом пути маршрута было.

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Райан предложил использовать Ограничения маршрута .И это, кажется, очень хороший вариант.Хотя регулярные выражения обычно добавляют сложность, я думаю, что это довольно просто:

[Route("[controller]/{direction:regex(^(up|down)$)}/{id}")]
public IActionResult Move(string action, string direction, int id)

Как и ожидалось action=Move и direction=up.

Преимущество состоит в том, что только up и down доступны как маршруты, и это не мешает другим маршрутам.

0 голосов
/ 14 ноября 2018

Вместо жесткого кодирования направления как «вверх» и «вниз» в объявлении маршрута, вы можете рассматривать это как параметр. Поскольку вы использовали ключевое слово «действие» в качестве параметра, во время привязки параметра ему будет присвоен фактический метод действия, выбранный платформой.

Вы можете попробовать следующий код -

[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);
    }
}
...