15

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

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

现在,在过去(当我不使用 ViewModel,例如 R&D 时),我有一个这样的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 不知道如何Post从 a 更新 a ExistingPostViewModel(之前是Post-> Post)。

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

但后来我基本上压倒了一切。我不想这样做并且破坏了削减 ViewModel 的要点。

谁能解惑我?

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

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

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

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

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

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

4

3 回答 3

2

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

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

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

于 2011-05-05T12:41:45.280 回答
1

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

于 2016-04-18T20:01:26.390 回答
0

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

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

于 2011-05-05T12:58:12.760 回答