Методы GET и POST с одинаковым именем действия в одном контроллере
почему это неправильно?
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
Some Code--Some Code---Some Code
return View();
}
[HttpPost]
public ActionResult Index()
{
Some Code--Some Code---Some Code
return View();
}
}
Как я могу иметь контроллер, который отвечает на одну вещь, когда" getted "и один, когда"posted"?
8 ответов:
Так как вы не можете иметь два метода с одинаковым именем и подписью, Вы должны использовать
ActionName
:[HttpGet] public ActionResult Index() { Some Code--Some Code---Some Code return View(); } [HttpPost] [ActionName("Index")] public ActionResult IndexPost() { Some Code--Some Code---Some Code return View(); }
см. Также "как метод становится действием"
пока ASP.NET MVC позволит вам иметь два действия с одинаковым именем, .NET не позволит вам иметь два метода с одинаковой сигнатурой - т. е. с одинаковым именем и параметрами.
вам нужно будет назвать методы по-разному использовать атрибут ActionName, чтобы сказать ASP.NET MVC, что они на самом деле одно и то же действие.
тем не менее, если вы говорите о GET и POST, Эта проблема, скорее всего, исчезнет, так как действие POST будет принимать больше параметров, чем GET и поэтому быть различимым.
Итак, вам нужно либо:
[HttpGet] public ActionResult ActionName() {...} [HttpPost, ActionName("ActionName")] public ActionResult ActionNamePost() {...}
или
[HttpGet] public ActionResult ActionName() {...} [HttpPost] public ActionResult ActionName(string aParameter) {...}
Мне нравится принимать сообщение формы для моих действий по сообщению, даже если мне это не нужно. Для меня это просто кажется правильным, как вы якобы публикуете что-то.
public class HomeController : Controller { public ActionResult Index() { //Code... return View(); } [HttpPost] public ActionResult Index(FormCollection form) { //Code... return View(); } }
чтобы ответить на ваш конкретный вопрос, вы не можете иметь два метода с одинаковым именем и одинаковыми аргументами в одном классе; использование атрибутов HttpGet и HttpPost не различает методы.
чтобы решить эту проблему, я обычно включаю модель представления для формы, которую вы публикуете:
public class HomeController : Controller { [HttpGet] public ActionResult Index() { Some Code--Some Code---Some Code return View(); } [HttpPost] public ActionResult Index(formViewModel model) { do work on model -- return View(); } }
Не может мульти действие то же имя и тот же параметр
[HttpGet] public ActionResult Index() { return View(); } [HttpPost] public ActionResult Index(int id) { return View(); }
хотя int id не используется
вы не можете иметь несколько действий с одинаковым именем. Вы можете добавить параметр к одному методу, и это будет допустимо. Например:
public ActionResult Index(int i) { Some Code--Some Code---Some Code return View(); }
есть несколько способов сделать, чтобы иметь действия, которые отличаются только по глаголу запроса. Мой любимый и, я думаю, самый простой в реализации является использование AttributeRouting пакета. После установки просто добавьте атрибут к вашему методу следующим образом:
[GET("Resources")] public ActionResult Index() { return View(); } [POST("Resources")] public ActionResult Create() { return RedirectToAction("Index"); }
в приведенном выше примере методы имеют разные имена но имя действия в обоих случаях - "ресурсы". Единственное различие-это глагол запроса.
пакет может быть установлен с помощью NuGet следующим образом:
PM> Install-Package AttributeRouting
Если вы не хотите зависимости от пакетов AttributeRouting, вы можете сделать это, написав пользовательский атрибут селектора действий.
вы получили хороший ответ на этот вопрос, но я хочу добавить свои пять копеек. Вы можете использовать один метод и обрабатывать запросы в соответствии с типом запроса:
public ActionResult Index() { if("GET"==this.HttpContext.Request.RequestType) { Some Code--Some Code---Some Code for GET } else if("POST"==this.HttpContext.Request.RequestType) { Some Code--Some Code---Some Code for POST } else { //exception } return View(); }
сегодня я проверял некоторые ресурсы по тому же вопросу, и я получил очень интересный пример.
можно вызвать тот же метод по протоколу GET и POST, но вам нужно перегрузить параметры следующим образом:
@using (Ajax.BeginForm("Index", "MyController", ajaxOptions, new { @id = "form-consulta" })) { //code }
действие:
[ActionName("Index")] public async Task<ActionResult> IndexAsync(MyModel model) { //code }
по умолчанию метод без явного протокола GET, но в этом случае есть объявленный параметр, который позволяет методу работать как сообщение.
когда GET is выполненный параметр не имеет значения, но при выполнении POST параметр требуется по вашему запросу.