【问题标题】:How to update Model when binding to a ViewModel?绑定到 ViewModel 时如何更新模型?
【发布时间】:2011-08-19 01:42:17
【问题描述】:

我有一个像这样的[HttpPost] 操作方法签名:

[HttpPost]
public ActionResult Edit(ExistingPostViewModel model)
{
   // Save the edited Post.
}

现在,在过去(当我不使用 ViewModel,例如研发时),我有一个 Edit 方法的实现,如下所示:

[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 不知道如何从 ExistingPostViewModel 更新 Post(之前是 Post -> Post)。

现在,我正在使用 AutoMapper。所以我想我可以从 ViewModel 映射到Post,然后保存帖子。

但是我基本上覆盖了一切。我不想这样做并且破坏了削减 ViewModel 的要点。

谁能解惑我?

这似乎是一个非常常见的场景,我完全不知道人们如何解决这个问题。我只能看到 3 种可能的解决方案:

  1. 不要在 HTTP POST 中使用 ViewModel。正如我所说,我过去为研发而这样做并且它有效,但现在我看到我的视图是如何演变的(验证、简单),我不能仅仅为了这个问题而妥协。

  2. 不要使用 TryUpdateModel。可能,但是我将如何合并更改?

  3. 使用从左到右。啊。但目前这似乎是我倾向于的方式。

有人请给我解决方案#4! :)

顺便说一句,我正在使用 ASP.NET MVC 3、Razor 和实体框架。

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 viewmodel model-binding updatemodel


    【解决方案1】:

    我实际上在我目前正在进行的一个项目中遇到了同样的问题。尽管我不喜欢它,但我最终还是采用了从左到右的方法并将我的视图模型数据手动映射回我的实体。

    这种方法的唯一好处是它确实为您提供了更多控制权。由于我开始使用更多的复合视图模型,实际上您的视图模型中包含来自多个实体的字段,因此以这种方式做事开始变得更有意义。

    我也在使用 AutoMapper,你说得对,当你尝试做一个简单的更新操作时,它确实会变得很尴尬。希望我为您提供一些超级聪明的解决方法,但“老式方法”似乎可以让我一直在做的工作做得最好。

    【讨论】:

    • Noooo.. :) 我不介意时不时地从左到右,但这意味着每个更新页面都需要这样做。确实应该有一个通用/简单的方法来做到这一点。我在每个视图上使用一个 ViewModel。因此,每个需要更新数据库的视图都需要 L-R。另外,我现在也需要大量隐藏字段。我的头好痛.... :(
    • 一直在等待,希望其他人会过来告诉我们有更好的方法。但我想没有。 :( +1 并被接受。
    【解决方案2】:

    不确定这是否会有所帮助,但它对我有用。我将基础域表作为访问者对象。我的视图模型包含访问者对象以及几个用于下拉列表的 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 对我的视图模型起作用,因为“Visitor”字符串告诉它要比较哪些值。

    【讨论】:

      【解决方案3】:

      对于简单的事情,您不必在实施更新之前运行任何控件,您正在执行的操作是可以的(db.get(),然后更新)。

      当事情变得复杂时,您必须加载实体,然后从视图模型中逐个属性地选择并应用用户的更改。在这些情况下,您最终会编写 Update 方法,该方法获取新数据作为输入,然后加载现有实体,然后比较状态,并根据视图模型数据采取所需的操作。实际上,在这种情况下,您可能不会有 Update 方法,但会有行为,例如 CancelPost、AddComment、EditPost(也记录编辑原因)、AddTagsToPost 等。

      【讨论】:

      • 是的,我有像AddComment 这样的行为方法。但这是一个基本的 CRUD 页面,我只想用传入的 ViewModel 中提供的值更新现有对象。它应该很简单,我不敢相信我必须手动比较属性的状态。这也意味着我需要整个表单中的隐藏字段。
      猜你喜欢
      • 2013-06-18
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2014-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多