在同一个控制器中具有相同操作名称的 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();
}


}

我怎样才能有一个控制器,回答一件事时,“获得”和一个时,是“张贴”?

126801 次浏览

Since you cannot have two methods with the same name and signature you have to use the ActionName attribute:

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


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

Also see "How a Method Becomes An Action"

Can not multi action same name and same parameter

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

althought int id is not used

To answer your specific question, you cannot have two methods with the same name and the same arguments in a single class; using the HttpGet and HttpPost attributes doesn't distinguish the methods.

To address this, I'd typically include the view model for the form you're posting:

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


}

While ASP.NET MVC will allow you to have two actions with the same name, .NET won't allow you to have two methods with the same signature - i.e. the same name and parameters.

You will need to name the methods differently use the ActionName attribute to tell ASP.NET MVC that they're actually the same action.

That said, if you're talking about a GET and a POST, this problem will likely go away, as the POST action will take more parameters than the GET and therefore be distinguishable.

So, you need either:

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


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

Or,

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


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

You can't have multiple actions with the same name. You could add a parameter to one method and that would be valid. For example:

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

There are a few ways to do to have actions that differ only by request verb. My favorite and, I think, the easiest to implement is to use the AttributeRouting package. Once installed simply add an attribute to your method as follows:

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


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

In the above example the methods have different names but the action name in both cases is "Resources". The only difference is the request verb.

The package can be installed using NuGet like this:

PM> Install-Package AttributeRouting

If you don't want the dependency on the AttributeRouting packages you could do this by writing a custom action selector attribute.

I like to accept a form post for my POST actions, even if I don't need it. For me it just feels like the right thing to do as you're supposedly posting something.

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


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

You received the good answer to this question, but I want to add my two cents. You could use one method and process requests according to request type:

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

Today I was checking some resources about the same question and I got an example very interesting.

It is possible to call the same method by GET and POST protocol, but you need to overload the parameters like that:

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

The action:

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

By default a method without explicit protocol is GET, but in that case there is a declared parameter which allows the method works like a POST.

When GET is executed the parameter does not matter, but when POST is executed the parameter is required on your request.