Методы 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();
}
}
Как я могу иметь контроллер, который отвечает на один вопрос, когда он "получен", и один, когда "опубликован"?
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) {...}
Мне нравится принимать форму сообщения для моих действий POST, даже если мне это не нужно. Для меня кажется, что это правильно, когда вы что- то публикуете.
public class HomeController : Controller
{
public ActionResult Index()
{
//Code...
return View();
}
[HttpPost]
public ActionResult Index(FormCollection form)
{
//Code...
return View();
}
}
Вы получили хороший ответ на этот вопрос, но я хочу добавить свои два цента. Вы можете использовать один метод и обрабатывать запросы в соответствии с типом запроса:
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();
}
Чтобы ответить на ваш конкретный вопрос, вы не можете иметь два метода с одинаковым именем и одинаковыми аргументами в одном классе; использование атрибутов 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();
}
}
Вы не можете иметь несколько действий с одним и тем же именем. Вы можете добавить параметр к одному методу, и это будет допустимо. Например:
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, вы можете сделать это, написав атрибут селектора настраиваемых действий.
Не может многократное действие с тем же именем и тем же параметром
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(int id)
{
return View();
}
althought int id не используется
Сегодня я проверил некоторые ресурсы по тому же вопросу и получил очень интересный пример.
Можно вызвать один и тот же метод по протоколу GET и POST, но вам необходимо перегрузить параметры следующим образом:
@using (Ajax.BeginForm("Index", "MyController", ajaxOptions, new { @id = "form-consulta" }))
{
//code
}
Действие:
[ActionName("Index")]
public async Task<ActionResult> IndexAsync(MyModel model)
{
//code
}
По умолчанию метод без явного протокола - GET, но в этом случае есть объявленный параметр, который позволяет методу работать как POST.
Когда выполняется GET, параметр не имеет значения, но когда выполняется POST, параметр требуется по вашему запросу.