我有一个带有相同签名的GET和POST方法,这会产生编译时错误。
[HttpGet]
public ActionResult MyAction(string myString)
{
// do some stuff
return View();
}
[HttpPost]
public ActionResult MyAction(string myOtherString)
{
// do different stuff
return View();
}
所以我必须在Get Request中对myString做一些事情,但是我必须在POST请求中使用myOtherString做其他事情。做一些研究我看到以下堆栈溢出答案 - post and get with same method signature
接受的答案是:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Friends()
{
// do some stuff
return View();
}
// Post:
[ActionName("Friends")]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Friends_Post()
{
// do some stuff
return View();
}
我的问题确实是 - 在接受的答案中,对“SomeController”,“朋友”的POST请求仍然会导致正在执行的Friends_Post操作?
答案 0 :(得分:2)
创建有效的操作方法有两个方面。 1)路由框架必须能够区分,2)它必须首先是可编译的代码。
进行一次GET和一次POST满足第一个要求:路由框架将知道要调用的操作。但是,从基本的C#角度来看,在同一个类中仍然有两个具有相同签名的方法:名称,参数类型和计数以及返回值。如果只改变其中一个因素,代码就可以编译。
最简单的方法,你实际上会在带有CRUD操作的脚手架控制器中看到这个,就是更改POST操作的名称,然后用ActionName
属性修饰它以保持URL相同。正如我所说,带有CRUD操作的脚手架控制器使用以下示例:
public ActionResult Delete(int id)
{
...
}
[HttpPost]
[ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
...
}
答案 1 :(得分:1)
我希望Post
能够获取对象/实体或至少是您实际更新或插入的ViewModel。所以,在朋友的情况下......
获取朋友列表......
[HttpGet]
public ActionResult MyAction(string myString)
{
//return all friends or friends that satisfy filter passed in...
}
不确定字符串是否必需,但可以用作过滤器。
至于帖子......
[HttpPost]
public ActionResult MyAction(Friend friend)
{
//add new friend
}
...或
[HttpPost]
public ActionResult MyAction(Friend friend, int id)
{
//update friend by id
}
您可以看到签名都不同,因为它们应该执行不同的操作。您可以使用相同的方法名称来调用它们,但这对于在您之后选择代码的开发人员来说并不是很有意义。 GetFriends / UpdateFriend / InsertFriend / UpsertFriend 等名称是不言自明的。
答案 2 :(得分:0)
创建一个视图模型以传递和回发,这将适用于您尝试执行的操作。
[HttpGet]
public ActionResult MyAction(string myString)
{
var model = new MyActionModel();
// do some stuff
return View(model);
}
[HttpPost]
public ActionResult MyAction(string myString, MyActionModel model)
{
// do different stuff
return View(model);
}
答案 3 :(得分:0)
您可以使用路由(> = MVC 5),具有相同签名和不同路由属性的Controller方法来实现此目的
[ActionName("ConfirmDelete")]
public ActionResult Delete(int id)
{
...
}
[ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
...
}