【问题标题】:Methods in MVC with same signatureMVC 中具有相同签名的方法
【发布时间】:2014-10-23 14:13:57
【问题描述】:

我有一个具有相同签名的 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 请求中对 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”、“Friends”的 POST 请求是否仍会导致 Friends_Post 操作被执行?

【问题讨论】:

  • 应该可以,你试过了吗?
  • 动作在做什么? 方法 的名称应该代表它将完成的工作。在上面的例子中,我可能会使用GetFriendsUpdateFriendInsertFriendetc
  • 是的,它会执行 Friends_Post。
  • @christiandev 提出了一个很好的观点,也许你的控制器应该命名为FriendsController,而你的方法应该命名为ListUpdate(如果是这样的话)。
  • 我会保持名称不变,但在 get 中构造并返回一个模型,并在 post 中接受一个模型。

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


【解决方案1】:

创建有效的操作方法有两个方面。 1) 路由框架必须能够区分,2) 首先它必须是可编译的代码。

创建一个 GET 和一个 POST 满足第一个要求:路由框架将知道要调用哪个操作。但是,从基本的 C# 角度来看,在同一个类中仍然有两个具有相同签名的方法:名称、参数类型和计数以及返回值。如果只改变其中一个因素,代码就可以编译。

最简单的方法是更改​​ POST 操作的名称,然后用ActionName 属性对其进行修饰以保持 URL 不变,并且您实际上会看到它在带有 CRUD 操作的脚手架控制器中使用。正如我所说,带有 CRUD 操作的脚手架控制器使用以下示例:

public ActionResult Delete(int id)
{
    ...
}

[HttpPost]
[ActionName("Delete")]
public ActionResult DeleteConfirm(int id)
{
    ...
}

【讨论】:

    【解决方案2】:

    我希望Post 获取一个对象/实体,或者至少是你实际更新或插入的视图模型。所以,对于朋友...

    要获取朋友列表...

    [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 等名称是不言自明的。

    【讨论】:

      【解决方案3】:

      创建一个视图模型以传递和回发,这将适用于您正在尝试做的事情。

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

      【讨论】:

        【解决方案4】:

        您可以使用 Routing(>=MVC 5),具有相同签名和不同路由属性的控制器方法来实现此目的

        [ActionName("ConfirmDelete")]
            public ActionResult Delete(int id)
        {
            ...
        }
        
        [ActionName("Delete")]
        public ActionResult DeleteConfirm(int id)
        {
            ...
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-07
          • 1970-01-01
          • 2021-11-12
          • 1970-01-01
          相关资源
          最近更新 更多