OBTENER y POST en la misma acción del controlador en ASP.NET MVC

91

Me gustaría tener una sola acción que responda tanto a Gets como a Posts. Intenté lo siguiente

[HttpGet]
[HttpPost]
public ActionResult SignIn()

Eso no pareció funcionar. Alguna sugerencia ?

Cranialsurge
fuente
2
Para explicar el problema: La acción se ignora. Cada atributo excluirá todos los demás métodos de solicitud, por lo que la acción termina no aceptando ningún método de solicitud.
Guffa
En ASP.NET MVC2 y VisualStudio 2010, el ejemplo de OP (con "[AcceptVerbs (HttpVerbs.Get)]", etc.) da el error de compilación: "Atributo 'AcceptVerbs' duplicado".
DaveD
4
@Dave ¿Estás haciendo [AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]o [AcceptVerbs(HttpVerbs.Get)][AcceptVerbs(HttpVerbs.Post)]? No sé nada sobre esos atributos, pero si está haciendo el segundo, puede que sea por eso que está obteniendo ese error.
Jared

Respuestas:

134

Esto es posible utilizando el atributo AcceptVerbs. Es un poco más detallado pero más flexible.

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

Más sobre msdn .

Ryan Bair
fuente
3
Sí, pero ¿qué pasa si el método usa parámetros (por ejemplo, SignIn (parámetros SingInParams) ... para GET, se toman de URI (por lo que [FromUri] debe especificarse) y para POST se toman del cuerpo (entonces [ FromBody] tiene que ser especificado)?
michal.jakubeczy
64

Las acciones responden tanto a GET como a POST de forma predeterminada, por lo que no tiene que especificar nada:

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

Dependiendo de su necesidad, aún puede realizar una lógica diferente según el HttpMethod operando en el valor HttpContext.Request.HttpMethod.

Kurt Schindler
fuente
5
¡Esto está bien hasta que intente usar modelos de vista! en la acción de publicación que normalmente pasaría en el modelo de vista, intenté usar un parámetro opcional y lo predeterminé en nulo, pero eso no funciona.
JBeckton
1
@JBeckton Por lo general, tengo un método GET que solo tiene parámetros de cadena de consulta SignIn(Guid? UserId)y POST tiene un modelo de vista SignIn(SomeVM vm)y ambos llaman a un método privado compartido SignInHandleGetPost(...)... que tal vez tome una VM que el método GET debe inicializar, o parámetros opcionales, o lo que prefiera hacer para refactorizar el código reutilizable / compartido.
AaronLS
2
@JBeckton Acabo de probarlo ahora con el proyecto de muestra ASP.NET MVC 4.6.1, con el método AccountController.Login(String returnUrl, LoginViewModel model)y funciona bien. modeles nulo en GET y no nulo en POST. Sin embargo [ValidateForgeryToken], debe anularse porque ValidateForgeryTokengenera una excepción en las solicitudes GET.
Dai
0
[HttpGet]
public ActionResult SignIn()
{
}

[HttpPost]
public ActionResult SignIn(FormCollection form)
{
}
Neil Outler
fuente
Eso no es lo que estoy buscando, esa es la implementación MVC predeterminada de tener métodos separados para GET y POST a través de la sobrecarga de funciones. No soy nuevo en MVC, estoy tratando de que la acción GET también responda a ciertos eventos POST además de la acción POST estándar para la colección de formularios.
Cranialsurge
Entonces debes seguir la respuesta de Kurts. Ningún atributo manejará ambos. Si está intentando que las solicitudes POST vayan a diferentes acciones, eso no es posible. Tu acción tendrá que realizar el cambio que estás buscando.
Jeremy B.