RedirectToAction генерирует неправильный URL (параметр строки запроса вместо параметра Routedata)

Я использую атрибуты RouteAttributes в своих проектах, и они работают правильно, за исключением этого случая: у меня есть два одинаковых действия: одно принимает два параметра типа int, а другое - только одно.

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

Проблема в том, что в ActionResultExample(int idVar1)Я ожидаю, что будет перенаправлен на ControllerExample/Edit/idVar1/Brands/idVar2; Однако я перенаправлен на ControllerExample/Edit/idVar1/Brands?idVar2=idVar2, Это создает бесконечный цикл перенаправления, конечно.

Вот пример кода:

    [Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2}")]
    public ActionResult ActionResultExample(int idVar1, int idVar2)
    {
        var objectForView= ObjectController.Get(idVar1, idVar2);

        return View("ActionResultExample", objectForView);
    }

    [Route("ControllerExample/Edit/{idVar1}/Brands")]
    public ActionResult ActionResultExample(int idVar1)
    {
        ...
        var idVar2 = getDefaultVar2();
        return RedirectToAction("ActionResultExample", //redirects to ControllerExample/Edit/idVar1/Brands?idVar2=idVar2 instead of ControllerExample/Edit/idVar1/Brands/idVar2
            new {idVar1= idVar1, idVar2 = idVar2 });
    }

3 ответа

Вы можете сделать это с 1 маршрутом и 1 методом действия:

Здесь мы используем? чтобы обозначить, что последний параметр URL является необязательным, и мы делаем то же самое в методе действия, используя аргумент метода по умолчанию.

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2?}")]
public ActionResult ActionResultExample(int idVar1, int? idVar2 = null)
{
    var idVar2Int = !idVar2.HasValue ? getDefaultVar2() : idVar2.Value;
    var objectForView= ObjectController.Get(idVar1, idVar2Int);

    return View("ActionResultExample", objectForView);
}

Если вы действительно хотите использовать это как 2 отдельных метода действий, вам может потребоваться обновление до System.Web.Mvc 5.1 (что можно сделать с помощью nuget). Затем вы можете использовать параметр Order в RouteAttribute. Однако вам также следует переименовать хотя бы один из методов действия, поскольку в MVC не должно быть двух перегрузок GET с одинаковым именем:

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2}", Order = 1)]
public ActionResult ActionResultExample(int idVar1, int idVar2)
{
    var objectForView= ObjectController.Get(idVar1, idVar2);

    return View("ActionResultExample", objectForView);
}

[Route("ControllerExample/Edit/{idVar1}/Brands", Order = 2)]
public ActionResult ActionResultExampleWithoutDefaults(int idVar1)
{
    ...
    var idVar2 = getDefaultVar2();
    return RedirectToAction("ActionResultExample", //redirects to ControllerExample/Edit/idVar1/Brands?idVar2=idVar2 instead of ControllerExample/Edit/idVar1/Brands/idVar2
        new {idVar1= idVar1, idVar2 = idVar2 });
}

Я еще не использовал RouteAttribute, но это похоже на проблему заказа.

Проверьте http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

Старый способ сделать маршрутизацию в.\App_Start\RouteConfig.cs вы должны были правильно упорядочить ваши маршруты. И если все остальное не удалось, последний маршрут был использован.

Поэтому, используя атрибут RouteAttribute, вам нужно установить порядок для ваших маршрутов. Может быть, это возможно с RouteAttribute, может быть, это не так. Если это не так, вам придется вернуться к старому способу ведения дел.

Использование одного и того же имени для всех параметров не поддерживается, так как ASP.NET MVC не может различить, если вы хотите перейти к маршруту с idVar1 и idVar2 в качестве значений маршрута или использовать idVar2 в качестве значения строки запроса. Измените код на второй метод, чтобы использовать другое имя значения маршрута:

    [Route("ControllerExample/Edit/{idVar3}/Brands")]
    public ActionResult ActionResultExample(int idVar3)
    {
        var idVar2 = 100;
        return RedirectToAction("ActionResultExample",
            new { idVar1 = idVar3, idVar2 = idVar2 });
    }

Это должно работать как ожидалось.

Но если вы используете 2 метода только для предоставления значения по умолчанию для idVar2, обратите внимание, что вам это не нужно. Ты можешь сделать:

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2=100}")]

Чтобы установить значение по умолчанию 100. Или используйте обнуляемый тип на контроллере:

[Route("ControllerExample/Edit/{idVar1}/Brands/{idVar2?}")]
 public ActionResult ActionResultExample(int idVar1, int? idVar2)

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

Другие вопросы по тегам