MVC中具有相同签名的方法
本文关键字:方法 MVC | 更新日期: 2023-09-27 18:27:39
我有一个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。在做一些研究时,我看到了以下堆栈溢出的答案,并用相同的方法获得了签名
接受的答案是:
[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"、"Friends"的POST请求是否仍然会导致Friends_POST操作被执行?
创建有效的操作方法有两个方面。1) 路由框架必须能够做出区分,2)它必须首先是可编译的代码。
制作一个GET和一个POST满足第一个要求:路由框架将知道要调用哪个操作。然而,从基本的C#角度来看,在同一个类中仍然有两个方法具有相同的签名:名称、参数类型和计数以及返回值。如果只更改其中一个因素,代码就可以编译。
最简单的方法是更改POST操作的名称,然后用ActionName
属性对其进行修饰,以保持URL不变。正如我所说,具有CRUD操作的脚手架控制器使用以下作为示例:
public ActionResult Delete(int id)
{
...
}
[HttpPost]
[ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
...
}
我希望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/UsertFriend等名称不言自明。
创建一个视图模型来传递和发布,这将适用于您想要做的事情。
[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);
}
您可以使用路由(>=MVC 5)、具有相同签名和不同路由属性的控制器方法来实现这一点
[ActionName("ConfirmDelete")]
public ActionResult Delete(int id)
{
...
}
[ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
...
}