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操作被执行?

MVC中具有相同签名的方法

创建有效的操作方法有两个方面。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)
{
    ...
}