2012-03-04 49 views
65

为什么这不正确?在同一控制器中使用相同操作名称的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(); 
     } 

    } 

怎样才可以有一个controlller全髋关节置换答案一件事时,“getted”,一个当“贴”?

回答

130

既然你不能有两个方法具有相同的名称和签名,你必须使用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(); 
    } 

另见"How a Method Becomes An Action"

+0

我知道它太迟问不了。但有可能有两个不同的HttpPost操作方法具有相同的名称,并采用不同的参数。我说的是,我需要过滤器应用到其已定义 – Vini 2015-11-16 09:34:40

+0

是的,这是可能的,因为它是一个有效的.NET方法签名HttpPost方法的创建方法的情况。方法被重载(方法重载)。 – nwolisa 2017-12-13 01:02:23

2

不能多动作相同的名称和参数

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

虽然int id未使用

+1

如果id是一个不可为空的int,它会真的有效吗? – jahu 2014-01-28 10:19:47

5

要回答您的具体问题,您不能在同一个类中使用两个具有相同名称和相同参数的方法;使用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(); 
    } 

} 
32

虽然ASP.NET MVC可以让你有相同的名称,.NET两个动作将不允许您使用两个具有相同签名的方法 - 即具有相同的名称和参数。

您需要命名方法不同使用ActionName属性告诉ASP.NET MVC,他们实际上是相同的动作。

这就是说,如果你在谈论一个GET和POST一个,这个问题可能会消失,因为POST操作将花费比获得更多的参数,因此可以区分的。

所以,你需要两种:

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

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

或者,

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

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

你不能有多个同名动作。你可以添加一个参数到一个方法,这是有效的。例如:

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>安装,包装AttributeRouting

如果你不希望你能做到这一点的AttributeRouting包的相关性通过编写自定义动作选择做属性。

12

我喜欢接受表单POST我的POST动作,即使我并不需要它。对于我来说,感觉就像正确的事做,因为你理应发布东西

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

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

简单的精彩讲解 – Ali 2015-01-10 15:07:44

+1

唯一的问题是,这触发喷砂HttpRequestValidationException即使[AllowHtml]等。不,这是一个不好的例外,但它的实现,而当它被触发(特别是当它在一个地区被触发)是不必要的不透明。 – Ted 2015-07-10 21:20:11

1

您收到了这个问题的良好答案,但我想补充我的两分钱。您可以根据请求类型使用一种方法和处理请求:

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(); 
} 
相关问题