具有相同签名的MVC中的方法

时间:2014-10-23 14:13:57

标签: c# .net asp.net-mvc asp.net-mvc-4

我有一个带有相同签名的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操作?

4 个答案:

答案 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)
{
    ...
}