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)
Обратите внимание, что имя значения маршрута заканчивается знаком вопроса в атрибуте маршрута, чтобы установить его как необязательный параметр.