Asp.net mvc routing: как использовать действие по умолчанию, но не по умолчанию?
Я переписываю вопрос, поскольку ответы пока показывают мне, что я не определил его достаточно хорошо. Я оставлю исходный вопрос для справки ниже.
При настройке маршрутизации вы можете указать значения по умолчанию для разных частей URL/маршрута. Рассмотрим пример, который создает мастер VS:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional } // Parameter defaults
В этом примере, если контроллер не указан, будет использоваться DefaultPageController, и если действие не указано, будет использовано действие "Индекс" .
URL-адреса будут выглядеть следующим образом: http://mysite/MyController/MyAction
.
Если в Url нет такого действия: http://mysite/MyController
, тогда будет использоваться действие индекса.
Теперь предположим, что у меня есть два действия в моем контроллере Index и AnotherAction. Соответствующие им URL-адреса http://mysite/MyController
и http://mysite/MyController/AnotherAction
соответственно. Мое действие "Индекс" принимает параметр, id. Поэтому, если мне нужно передать параметр в действие индекса, я могу сделать это: http://mysite/MyController/Index/123
. Обратите внимание, что в отличие от URL http://mysite/MyController
, я должен явно указать действие индекса. То, что я хочу сделать, - это передать http://mysite/MyController/123
вместо http://mysite/MyController/Index/123
. Мне не нужен "Индекс" в этом URL-адресе. Я хочу, чтобы движок mvc распознал, что, когда я запрашиваю http://mysite/MyController/123
, 123 не является действием (потому что я не определил действие с этим именем), но параметр мое действие по умолчанию "Индекс" . Как настроить маршрутизацию для достижения этой цели?
Ниже приведена оригинальная формулировка вопроса.
У меня есть контроллер с двумя методами, описанными как
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(SomeFormData data)
{
return View();
}
Это позволяет обрабатывать Url как http://website/Page
, когда пользователь переходит к этому URL-адресу (GET), а затем после этого возвращает форму (POST).
Теперь, когда я обрабатываю сообщение назад, в некоторых случаях я хочу перенаправить браузер на этот URL:
http://website/Page/123
Где 123 - некоторое целое число, и мне нужен метод для обработки этого URL-адреса в моем контроллере.
Как настроить маршрутизацию, так что это работает? В настоящее время у меня есть "по умолчанию" маршрутизация, созданная мастером, например:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional } // Parameter defaults
Я попробовал добавить еще один такой метод контроллера:
public ActionResult Index(int id)
{
return View();
}
Но это не работает, поскольку выбрано неоднозначное исключение действия:
Текущий запрос на действие "Индекс" на контроллере типа 'PageController' неоднозначно между следующими методы действий: System.Web.Mvc.ActionResult Index() on Тип PageController System.Web.Mvc.ActionResult Индекс (Int32) по типу PageController
Я должен добавить, что у меня также есть другие действия в этом контроллере. Это будет работать, если я этого не сделаю.
Ответы
Ответ 1
Вот как это можно решить:
Вы можете создать ограничение маршрута, чтобы указать движку маршрутизации, что если у вас есть что-то в URL-адресе, которое выглядит как число (123), то это параметр действия для действия по умолчанию, и если у вас есть что-то, что не похоже на number (AnotherAction), то это действие.
Рассмотрим этот код:
routes.MapRoute(
"MyController", "MyController/{productId}",
new {controller="My", action="Index"},
new {productId = @"\d+" });
Это определение маршрута будет соответствовать только числовым значениям после MyController в http://mysite/MyController/123
чтобы оно не мешало вызвать другое действие на том же контроллере.
Источник: создание ограничения маршрута
Ответ 2
Если вы сохраните имя переменной, чтобы оставаться идентификатором, вам ничего не нужно менять.
Переименуйте сообщение в "PostIndex" и добавьте этот атрибут:
[ActionName("Index")]
Тот же вопрос о SO здесь.
Хорошо, вот вам ответ для вырезания/вставки, если это поможет.
public ActionResult Index() {
return View();
}
[AcceptVerbs(HttpVerbs.Post), ActionName("Index")]
public ActionResult PostIndex(SomeFormData data) {
return View();
}
Ответ 3
О, я понял это сейчас. Я думаю, что это невозможно с использованием маршрута по умолчанию, вам нужно сопоставить пользовательские маршруты.
// /MyController/AnotherAction
routes.MapRoute(
null,
"MyController/AnotherAction",
new { controller = "DefaultPage", action = "AnotherAction" }
);
// /MyController
// /MyController/id
routes.MapRoute(
null,
"MyController/{id}",
new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional }
);
пс. По умолчанию маршруты, например /MyController/id, должны отображаться последним.
Ответ 4
Я думаю, вы хотите вернуться к тому же взгляду, но вам нужно понять, что вы делаете две разные вещи. Один из них получает сообщение, а другой - через get, а другой - через get и parameter...
Вы должны сделать 3 actionresult с разными именами и вернуть тот же вид, что и View ( "ThisIsTheResult" )