在同一个Controller中具有相同Action名称的GET和POST方法

时间:2012-03-04 06:07:41

标签: c# asp.net-mvc asp.net-mvc-3

为什么这不正确?

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

    }

我怎样才能让控制器在“天赋”时回答一件事,在“张贴”时回答一件事?

8 个答案:

答案 0 :(得分:158)

由于您不能使用两个具有相同名称和签名的方法,因此必须使用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"

答案 1 :(得分:35)

虽然ASP.NET MVC允许您使用相同名称的两个操作,但.NET不允许您使用相同签名的两个方法 - 即相同的名称和参数。

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

也就是说,如果你正在谈论GET和POST,这个问题可能会消失,因为POST动作将采用比GET更多的参数,因此可以区分。

所以,你需要:

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

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

或者,

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

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

答案 2 :(得分:16)

我喜欢接受我的POST操作的表单帖子,即使我不需要它。对我来说,感觉这是正确的,因为你应该发布 某些东西

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

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

答案 3 :(得分: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();
    }

}

答案 4 :(得分:2)

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

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

althought int id未使用

答案 5 :(得分: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包,则可以通过编写自定义操作选择器属性来完成此操作。

答案 6 :(得分: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();
}

答案 7 :(得分:0)

今天我正在检查有关同一问题的一些资源,我得到了一个非常有趣的例子。

可以通过GET和POST协议调用相同的方法,但是你需要重载这样的参数:

@using (Ajax.BeginForm("Index", "MyController", ajaxOptions, new { @id = "form-consulta" }))
{
//code
}

行动:

[ActionName("Index")]
public async Task<ActionResult> IndexAsync(MyModel model)
{
//code
}

默认情况下,没有显式协议的方法是GET,但在这种情况下,有一个声明的参数允许该方法像POST一样工作。

执行GET时,参数无关紧要,但执行POST时,您的请求需要参数。