在同一控制器中具有相同Action名称的GET和POST方法

本文关键字:GET POST 方法 控制器 Action | 更新日期: 2023-09-27 18:26:50

为什么不正确?

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

我怎么能让一个控制器在"获取"answers"发布"时回答一件事?

在同一控制器中具有相同Action名称的GET和POST方法

由于不能有两个具有相同名称和签名的方法,因此必须使用ActionName属性:

[HttpGet]
public ActionResult Index()
{
  // your code
  return View();
}
[HttpPost]
[ActionName("Index")]
public ActionResult IndexPost()
{
  // your code
  return View();
}

另请参阅"方法如何变成行动"

虽然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) {...}

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

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

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

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

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

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

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

althouth int id未使用

不能有多个具有相同名称的操作。您可以在一个方法中添加一个参数,这将是有效的。例如:

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

在上面的例子中,方法有不同的名称,但两种情况下的操作名称都是"Resources"。唯一的区别是请求动词。

该包可以使用NuGet安装,如下所示:

PM>安装包属性路由

如果您不希望依赖AttributeRouting包,可以通过编写自定义操作选择器属性来实现。

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

通过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时,请求中需要参数。