绑定到 ViewModel 时如何更新 Model?

发布于 2024-11-05 01:13:16 字数 1294 浏览 0 评论 0原文

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

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

现在,在过去(当我没有使用 ViewModels 时,例如研发),我有一个 Edit< 的实现/strong> 这样的方法:

[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 之前) -> ; 发布)。

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

但我基本上凌驾于一切之上。我不想这样做,并且违背了削减 ViewModel 的目的。

谁能帮我解惑吗?

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

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

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

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

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

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

I have an [HttpPost] action method signature like this:

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

Now, in the past (when i didn't use ViewModels, e.g R&D), i had an implementation of an Edit method like this:

[HttpPost]
public ActionResult Edit(Post model)
{
    var existingPost = repo.Find(model.Id);
    TryUpdateModel(existingPost);
    repo.Save(existingPost);  
    return RedirectToAction("Success", existingPost.Id);
}

Which worked great.

But i'm confused how to adapt the above to the ViewModel approach.

If i do this:

TryUpdateModel(existingPost)

With my ViewModel approach, not much happens. No errors, but nothing is being updated because MVC won't know how to update a Post from a ExistingPostViewModel (before it was Post -> Post).

Now, i'm using AutoMapper. So i thought i could map from the ViewModel to the Post, then save the post.

But then im basically overriding everything. Which i don't want to do and defeats the point of the cut down ViewModel.

Can anyone un-confuse me?

This seems like a really common scenario, and i am totally stumped as to how people solve this. I can only see 3 possible solutions:

  1. Don't use a ViewModel in the HTTP POST. As i said i did this in the past for R&D and it works, but now i see how my View's have evolved (validation, simplicity), and i can't compromise that just for the sake of this problem.

  2. Don't use TryUpdateModel. Possibly, but then how would i merge in the changes?

  3. Use left-to-right. Ugh. But at the moment this seems to be the way im leaning.

Someone please give me solution #4! :)

BTW, i'm using ASP.NET MVC 3, Razor and Entity Framework.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

淡看悲欢离合 2024-11-12 01:13:16

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

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

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

I actually ran into this exact same issue in a project I'm currently working on. As much as I wasn't a fan of it, I ended up doing the left to right approach and manually mapping my viewmodel data back to my entity.

The only nice thing about this approach is it does give you more control. Since I started using more compound viewmodels, where you actually have fields from more than one entity in your viewmodel, it started making more sense to do things this way.

I'm also using AutoMapper, and you're absolutely right, it does get awkward when you're trying to do a simple update operation. Wish I had some super clever workaround for you, but the "old fashioned way" seems to get the job done best for the work I've been doing.

无语# 2024-11-12 01:13:16

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

Not sure if this will help, but it is working for me. I have my underlying domain table as a Visitor Object. My viewmodel contains the Visitor Object plus a couple of IEnumerables for dropdowns.

    [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");

    }

The UpdateModel works off my viewmodel because of the "Visitor" string telling it what values to compare.

万劫不复 2024-11-12 01:13:16

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

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

For simple things where you don't have to run any controls prior to implementing the update what you are doing is okay (db.get(), and then update).

When things get complicated, you have to load the entity, and then select and apply user's changes from the view model, property by property. In those cases, you end up writing Update methods, which gets the new data as input, and then you load the existing entity, then compare states, and take the required actions based on the view model data. Actually in this case, probably you wont have an Update method but will have behaviors, like CancelPost, AddComment, EditPost (which also logs the edit reason), AddTagsToPost etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文