GET и POST в одно и то же действие контроллера в ASP.NET MVC

91

Я бы хотел, чтобы одно действие отвечало как на получение, так и на сообщения. Я пробовал следующее

[HttpGet]
[HttpPost]
public ActionResult SignIn()

Похоже, это не сработало. Какие-либо предложения ?

Краниальный хирург
источник
2
Чтобы объяснить проблему: действие игнорируется. Каждый атрибут будет исключать все другие методы запроса, поэтому действие в конечном итоге не принимает никаких методов запроса.
Guffa
В ASP.NET MVC2 и VisualStudio 2010 пример OP (с «[AcceptVerbs (HttpVerbs.Get)]» и т. Д.) Дает ошибку компиляции: «Дублировать атрибут AcceptVerbs».
DaveD
4
@ Дэйв. Ты делаешь [AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]или [AcceptVerbs(HttpVerbs.Get)][AcceptVerbs(HttpVerbs.Post)]? Я ничего не знаю об этих атрибутах, но если вы делаете второе, возможно, именно поэтому вы получаете эту ошибку.
Джаред

Ответы:

134

Это возможно с помощью атрибута AcceptVerbs. Он немного более подробный, но более гибкий.

[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]
public ActionResult SignIn()
{
}

Подробнее на msdn .

Райан Бэр
источник
3
Да, но что, если метод использует параметры (например, SignIn (параметры SingInParams) ... для GET они берутся из URI (поэтому необходимо указать [FromUri]), а для POST они берутся из тела (так что [ FromBody] необходимо указать)?
michal.jakubeczy
64

Действия по умолчанию отвечают как на GET, так и на POST, поэтому вам не нужно ничего указывать:

public ActionResult SignIn()
{
    //how'd we get here?
    string method = HttpContext.Request.HttpMethod;
    return View();
}

В зависимости от ваших потребностей вы все равно можете выполнять различную логику в зависимости от HttpMethod, работая со значением HttpContext.Request.HttpMethod.

Курт Шиндлер
источник
5
это нормально, пока вы не попробуете использовать модели просмотра! в действии публикации, которое вы обычно передаете в модели просмотра, я попытался использовать необязательный параметр и по умолчанию имел значение null, но это не работает.
JBeckton
1
@JBeckton Обычно у меня есть метод GET, который просто имеет параметры строки запроса, SignIn(Guid? UserId)а POST имеет модель представления, SignIn(SomeVM vm)и оба вызывают общий частный метод SignInHandleGetPost(...)... который, возможно, принимает виртуальную машину, которую должен инициализировать метод GET, или дополнительные параметры, или все, что вы предпочитаете делать для рефакторинга умышленного / общего кода.
AaronLS
2
@JBeckton Я только что попробовал это сейчас с примером проекта ASP.NET MVC 4.6.1, с этим методом, AccountController.Login(String returnUrl, LoginViewModel model)и он отлично работает. modelимеет значение NULL при GET и ненулевое значение при POST. Однако [ValidateForgeryToken]необходимо переопределить, потому что ValidateForgeryTokenвыдает исключение при запросах GET.
Дай
0
[HttpGet]
public ActionResult SignIn()
{
}

[HttpPost]
public ActionResult SignIn(FormCollection form)
{
}
Нил Аутлер
источник
Это не то, что я ищу, это стандартная реализация MVC с отдельными методами для GET и POST с помощью перегрузки функций. Я не новичок в MVC, я пытаюсь, чтобы действие GET также отвечало на определенные события POST в дополнение к стандартному действию POST для коллекции форм.
Cranialsurge
Тогда вам нужно следовать ответу Курца. Никакой атрибут не будет обрабатывать оба. Если вы пытаетесь направить запросы POST к различным действиям, это невозможно. Ваше действие должно будет выполнить переключение, которое вы ищете.
Джереми Б.