【问题标题】:Error with ViewResult and ActionResult containing same parametersViewResult 和 ActionResult 包含相同参数时出错
【发布时间】:2011-06-09 13:18:13
【问题描述】:

在我的控制器中,我有一个 Edit GET 方法来显示视图,还有一个 Edit POST 方法来保存更改:

public ViewResult Edit(int id)
{
    //
}

[HttpPost]
public ActionResult Edit(int id)
{
    //
}

但我收到一条错误消息:

类型“Controllers.MyController”已经定义了一个名为“Edit”的成员,具有相同的参数类型

我该如何解决这个问题?

【问题讨论】:

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


    【解决方案1】:

    这是因为您将相同的参数传递给两个函数,尽管您在一个函数上指定了 HttpPost,但这是不允许的。您可以更改 Edit Post 函数的名称并在 Html.BeginForm() 中指定它或将参数更改为 FormCollection 而不是 int

    【讨论】:

      【解决方案2】:

      你必须阅读这篇(3.6 Signatures and overloading)关于函数重载的文章。

      函数重载

      在这种方法中,您可以拥有两个或多个具有相同名称的函数。但是 每个函数必须有不同的 签名(即不同类型的 参数,参数序列或 参数个数)。

      注意:返回类型不是参数的签名

      在您的代码中,您已经实现了具有相同名称和签名的两个函数。

      【讨论】:

        【解决方案3】:

        您可以实现视图模型,使 EditViewModel 包含您希望用户能够编辑的所有字段,并在您的 Edit GET 方法中返回这些字段,并为视图模型提供强类型视图。那么这意味着在您的 POST 方法中,您可以将 EditViewModel 作为参数传递,有点像这样:

        [HttpGet]
        public ViewResult Edit(int id)
        {
            //build and populate view model
            var viewModel = new EditViewModel();
            viewModel.Id = id;
            viewModel.Name = //go off to populate fields
        
            return View("", viewModel)
        }
        
        [HttpPost]
        public ActionResult Edit(EditViewModel viewModel)
        {
            //use data from viewModel and save in database
        }
        

        所以你的 GET 和 POST 方法会有不同的签名。希望这会有所帮助。

        【讨论】:

          【解决方案4】:

          对于另一个不太优雅的解决方案,想象一个具有“类似向导”结构的页面(视图)的站点,您希望将 ViewModel 从第 1 页传递到第 2 页,从第 2 页到第 3 页等。

          问题是“GET”版本的Page 2需要从Page 1接收模型,但在做回发时还需要将模型传递给Page 3。因此,任何“中间”页面的 GET 和 POST 版本都需要包含模型的签名。

          一种解决方法是简单地在签名中添加一个“垃圾参数”,使用 ? 确保它可以为空。

              [HttpGet]
              public ActionResult Page2(MyModel myModel)
              {
              }
          
              [HttpPost]
              public ActionResult Page2(MyModel myModel, int? i)
              {
              }
          

          【讨论】:

            【解决方案5】:

            我认为最简单的方法是在 global.asax.cs 文件中添加一个额外的可选参数:

            new { controller = "Home", action = "Index", id = UrlParameter.Optional, id2 = UrlParameter.Optional } // Parameter defaults
            

            并从

            更改您的第二个功能
            [HttpPost]
            public ActionResult Edit(int id)
            

            [HttpPost]
            public ActionResult Edit(int id, int id2)
            

            这样您就不必更改任何逻辑。因为第二个参数是可选的。如果您不提供价值,它不会抱怨。

            【讨论】:

              【解决方案6】:

              如果您在 POST 控制器方法上使用 View Model,请确保您的模型有一个空的构造函数。这让我发疯了。

              namespace app.Models
              {
                  public class UserEdit
                  {
                      public User User { get; set; }
              
                      public UserEdit() { }
                  }
              }
              

              【讨论】:

                【解决方案7】:

                你可以试试这个。

                    public ActionResult Edit()
                    {
                        return View();
                    }
                
                    [HttpPost]
                    [ActionName("Edit")]
                    public ActionResult EditPosted()
                    {
                        return View();
                    }
                

                【讨论】:

                  猜你喜欢
                  • 2014-08-27
                  • 1970-01-01
                  • 2012-12-02
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-12-24
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多