2012-03-04 30 views
65

¿Por qué es incorrecto?Métodos GET y POST con el mismo nombre de acción en el mismo controlador

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

    } 

¿Cómo puedo tener una respuesta controlller thas una cosa cuando se "getted" y uno cuando se "publicado"?

Respuesta

130

Puesto que no puede tener dos métodos con el mismo nombre y la firma tiene que utilizar el atributo 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(); 
    } 

Véase también "How a Method Becomes An Action"

+0

Sé que es demasiado tarde para preguntar. pero es posible tener dos métodos de acción HttpPost diferentes con el mismo nombre que toman diferentes parámetros. Estoy hablando de un caso en el que necesito aplicar filtros a un método de creación que ya tiene un método HttpPost definido – Vini

+0

Sí, es posible porque es una firma de método .Net válida. Los métodos están sobrecargados (Sobrecarga de método). – nwolisa

2

Puede acción no polivalentes mismo nombre y el mismo parámetro

[HttpGet] 
    public ActionResult Index() 
    { 
     return View(); 
    } 
    [HttpPost] 
    public ActionResult Index(int id) 
    { 
     return View(); 
    } 

aunque int id no se utiliza

+1

¿Funcionará realmente si id es un int no nulo? – jahu

5

Para responder a su pregunta específica, no puede tener dos métodos con el mismo nombre y los mismos argumentos en una sola clase; el uso de los atributos HttpGet y HttpPost no distingue los métodos.

Para hacer frente a esto, normalmente habría incluyen el modelo de vista de la forma usted está enviando:

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(); 
    } 

} 
32

Mientras ASP.NET MVC le permitirá tener dos acciones con el mismo nombre, .NET no le permitirá tener dos métodos con la misma firma, es decir, el mismo nombre y los mismos parámetros.

Tendrá que nombrar los métodos de manera diferente, use el atributo NombreAcción para decirle a ASP.NET MVC que en realidad son la misma acción.

Dicho esto, si se trata de un GET y un POST, este problema probablemente desaparecerá, ya que la acción POST tomará más parámetros que el GET y por lo tanto será distinguible.

Por lo tanto, es necesario o bien:

[HttpGet] 
public ActionResult ActionName() {...} 

[HttpPost, ActionName("ActionName")] 
public ActionResult ActionNamePost() {...} 

O

[HttpGet] 
public ActionResult ActionName() {...} 

[HttpPost] 
public ActionResult ActionName(string aParameter) {...} 
2

no se puede tener múltiples acciones con el mismo nombre. Podría agregar un parámetro a un método y eso sería válido. Por ejemplo:

public ActionResult Index(int i) 
    { 
     Some Code--Some Code---Some Code 
     return View(); 
    } 

Hay algunas maneras de hacer para tener acciones que difieren solo en el verbo de solicitud. Mi favorito y, creo, el más fácil de implementar es usar el paquete AttributeRouting. Una vez instalado, simplemente añadir un atributo a su método de la siguiente manera:

[GET("Resources")] 
    public ActionResult Index() 
    { 
     return View(); 
    } 

    [POST("Resources")] 
    public ActionResult Create() 
    { 
     return RedirectToAction("Index"); 
    } 

En el ejemplo anterior los métodos tienen diferentes nombres, pero el nombre de la acción en ambos casos es "Recursos". La única diferencia es el verbo de solicitud.

El paquete se puede instalar utilizando NuGet así:

PM> Install-Package AttributeRouting

Si no desea que la dependencia de los paquetes AttributeRouting que podría hacer esto escribiendo un selector de acción personalizada atributo.

12

Me gusta aceptar una publicación de formulario para mis acciones POST, incluso si no la necesito. Para mí, parece que es lo correcto, ya que supuestamente publica algo.

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     //Code... 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult Index(FormCollection form) 
    { 
     //Code... 
     return View(); 
    } 
} 
+0

simple explicación maravillosa – Ali

+1

El único problema es que esto dispara la HttpRequestValidationException arruinada incluso si [AllowHtml] etc. No es una mala excepción, pero su implementación y cuándo se activa (y particularmente cuando se desencadena en un área) es innecesariamente opaco. – Ted

1

Has recibido la respuesta correcta a esta pregunta, pero quiero añadir mi granito de arena. Puede usar un método y procesar solicitudes de acuerdo con el tipo de solicitud:

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(); 
} 
Cuestiones relacionadas