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 ?


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 .


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.


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)
{
}

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.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.