我有一个[HttpPost]
动作方法签名,如下所示:
[HttpPost]
public ActionResult Edit(ExistingPostViewModel model)
{
// Save the edited Post.
}
现在,在过去(当我没有使用ViewModel,例如R& D)时,我有一个编辑方法的实现,如下所示:
[HttpPost]
public ActionResult Edit(Post model)
{
var existingPost = repo.Find(model.Id);
TryUpdateModel(existingPost);
repo.Save(existingPost);
return RedirectToAction("Success", existingPost.Id);
}
哪个效果很好。
但我很困惑如何使上述内容适应ViewModel方法。
如果我这样做:
TryUpdateModel(existingPost)
使用我的ViewModel方法,没有太多事情发生。没有错误,但没有任何内容正在更新,因为MVC不知道如何从Post
(ExistingPostViewModel
- > Post
之前)更新Post
。< / p>
现在,我正在使用AutoMapper。所以我想我可以从ViewModel映射到Post
,然后保存帖子。
然后我基本上压倒一切。我不想这样做,并且打败了ViewModel。
有人可以让我迷惑吗?
这似乎是一种非常常见的情况,我对人们如何解决这个问题感到非常难过。我只能看到3种可能的解决方案:
不要在HTTP POST中使用ViewModel。正如我所说,我过去为R&amp; D做过这个并且它有效,但现在我看到我的View已经进化(验证,简单),并且我不能仅仅为了这个问题而妥协。
请勿使用TryUpdateModel。可能,但那么我将如何合并这些变化呢?
使用从左到右。啊。但目前这似乎是我倾向的方式。
有人请给我解决方案#4! :)
BTW,我正在使用ASP.NET MVC 3,Razor和Entity Framework。
答案 0 :(得分:2)
我实际上在我正在进行的项目中遇到了同样的问题。尽管我不是它的粉丝,但我最终做了从左到右的方法并手动将我的viewmodel数据映射回我的实体。
这种方法唯一的好处是它确实可以让你获得更多的控制权。自从我开始使用更多复合视图模型以来,你在视图模型中实际拥有来自多个实体的字段时,开始以这种方式做事更有意义。
我也在使用AutoMapper,你是绝对正确的,当你尝试进行简单的更新操作时,它确实很尴尬。希望我能为你做一些超级聪明的解决方法,但是“老式的方式”似乎让我的工作做得最好。
答案 1 :(得分:0)
对于在实现更新之前不必运行任何控件的简单事情,你正在做的事情是可以的(db.get(),然后更新)。
当事情变得复杂时,您必须加载实体,然后从视图模型中选择并应用用户的更改属性。在这些情况下,您最终编写Update方法,将新数据作为输入,然后加载现有实体,然后比较状态,并根据视图模型数据采取所需操作。实际上在这种情况下,可能你没有Update方法但会有行为,如CancelPost,AddComment,EditPost(也记录编辑原因),AddTagsToPost等。
答案 2 :(得分:0)
不确定这是否会有所帮助,但它对我有用。我将我的基础域表作为访问者对象。我的viewmodel包含访问者对象以及几个用于下拉列表的IEnumerables。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(int id)
{
Visitor Visitor = new Visitor();
Visitor = db.Visitors.FirstOrDefault(v => v.VisitorID == id);
UpdateModel(Visitor, "Visitor");
db.SaveChanges();
return RedirectToAction("Index");
}
UpdateModel使用我的viewmodel,因为&#34;访问者&#34;字符串告诉它要比较什么值。