【问题标题】: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();
}