Маршрутизация: текущий запрос на действие [...] неоднозначен между следующими методами действий
У меня есть вид, называемый Browse.chtml
, где пользователь может ввести поисковый запрос или оставить поле поиска пустым. При вводе условия поиска я хочу направить страницу на http://localhost:62019/Gallery/Browse/{Searchterm}
, и когда ничего не будет введено, я хочу направить браузер на http://localhost:62019/Gallery/Browse/Start/Here
.
Когда я пытаюсь это сделать, я получаю сообщение об ошибке:
Текущий запрос действия "Обзор" в типе контроллера "GalleryController" неоднозначен между следующими способами: System.Web.Mvc.ActionResult Browse (System.String) по типу AutoApp_MVC.Controllers.GalleryController System.Web.Mvc.ActionResult Browse (Int32, System.String) типа AutoApp_MVC.Controllers.GalleryController
Все, что я делаю с MVC, впервые. Я не уверен, что еще попробовать в этот момент.
public ActionResult Browse(string id)
{
var summaries = /* search using id as search term */
return View(summaries);
}
public ActionResult Browse(string name1, string name2)
{
var summaries = /* default list when nothing entered */
return View(summaries);
}
У меня также есть это в Global.asax.cs:
routes.MapRoute(
"StartBrowse",
"Gallery/Browse/{s1}/{s2}",
new
{
controller = "Gallery",
action = "Browse",
s1 = UrlParameter.Optional,
s2 = UrlParameter.Optional
});
routes.MapRoute(
"ActualBrowse",
"Gallery/Browse/{searchterm}",
new
{
controller = "Gallery",
action = "Browse",
searchterm=UrlParameter.Optional
});
Ответы
Ответ 1
На контроллере можно использовать только два метода действий с тем же именем, и для этого 1 должен быть [HttpPost]
, а другой должен быть [HttpGet]
.
Поскольку оба ваших метода - GET, вы должны либо переименовать один из методов действия, либо перенести его на другой контроллер.
Хотя ваши методы 2 Browse являются допустимыми перегрузками С#, селектор метода действия MVC не может определить, какой метод вызывать. Он попытается сопоставить маршрут с методом (или наоборот), и этот алгоритм не будет строго типизирован.
Вы можете выполнить то, что хотите, используя настраиваемые маршруты, указывающие на различные методы действий:
... в Global.asax
routes.MapRoute( // this route must be declared first, before the one below it
"StartBrowse",
"Gallery/Browse/Start/Here",
new
{
controller = "Gallery",
action = "StartBrowse",
});
routes.MapRoute(
"ActualBrowse",
"Gallery/Browse/{searchterm}",
new
{
controller = "Gallery",
action = "Browse",
searchterm = UrlParameter.Optional
});
... и в контроллере...
public ActionResult Browse(string id)
{
var summaries = /* search using id as search term */
return View(summaries);
}
public ActionResult StartBrowse()
{
var summaries = /* default list when nothing entered */
return View(summaries);
}
Возможно, вы также сможете сохранить методы действий одинаковыми в контроллере, применив атрибут [ActionName]
к одному, чтобы отличить его. Используя тот же Global.asax, что и выше, ваш контроллер будет выглядеть следующим образом:
public ActionResult Browse(string id)
{
var summaries = /* search using id as search term */
return View(summaries);
}
[ActionName("StartBrowse")]
public ActionResult Browse()
{
var summaries = /* default list when nothing entered */
return View(summaries);
}
Ответ 2
Я не знаю, когда вопрос был задан, это решение было доступно, но вы можете использовать:
Request.QueryString["key"]
Так что это должно хорошо работать для вашей проблемы:
[HttpGet]
public ActionResult Browse()
{
if( Request.QueryString["id"] != null )
var summaries = /* search using id as search term */
else /*assuming you don't have any more option*/
var summaries = /* default list when nothing entered */
return View(summaries);
}
Ответ 3
Я думаю, что дело в том, что вам не нужно неявно проверять параметры запроса с помощью класса запросов.
MVC выполняет сопоставление для вас (если вы не вносили серьезных изменений в маршруты MVC).
Таким образом, путь actionlink для
/umbraco/Surface/LoginSurface/Logout?DestinationUrl=/home/
автоматически будет доступен вашему (поверхностному) контроллеру с указанным параметром:
public ActionResult Logout(string DestinationUrl)
MVC выполняет работу.
Ответ 4
Добавьте следующий код в RouteConfig.cs перед маршрутом по умолчанию
routes.MapMvcAttributeRoutes();
И добавьте атрибуты маршрута в контроллер, как:
[Route("Cars/deteals/{id:int}")]
public ContentResult deteals(int id)
{
return Content("<b>Cars ID Is " + id + "</b>");
}
[Route("Cars/deteals/{name}")]
public ContentResult deteals(string name)
{
return Content("<b>Car name Is " + name + "</b>");
}