如何使用viewmodel

时间:2017-02-10 23:52:03

标签: c# asp.net-mvc entity-framework

我有一个大型实体(组织),我已经将一些字段划分为单独的视图,其中一个较小的字段子集具有多个ViewModel。如果用户以后需要更新这些字段,我也想使用这些相同的视图。

我对如何填充数据感到困惑。例如,我(可能是愚蠢地)认为如果我使用整个实体填充Get,那么将自动填充字段 - 就像我使用与整个实体关联的编辑视图一样。

有人能告诉我ViewModels是不是应该以这种方式使用,还是我只是不考虑明显的事情?

这是我当前的Get / Post基于我(可能很差)的假设。 CompanyInfo是组织内的字段的子集。这给了我令人沮丧的“动态代理”错误。

// GET: /Organization/CompanyInfo
public ActionResult CompanyInfo(ManageMessageId? message)
{
    ViewBag.StatusMessage =
    message == ManageMessageId.ConfirmEmail ? "Please confirm your email address to log in again." : "";

    var member = GetUserMember();
    var org = db.Organizations.Single(x => x.OrgId == member.OrgId);

    return View(org);
}

//
// POST: /Organization/CompanyInfo
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> CompanyInfo(CompanyInfoViewModel model)
{
    if (ModelState.IsValid)
    {
        var member = GetUserMember();
        var org = await db.Organizations.SingleAsync(x => x.OrgId == member.OrgId);
        org.StreetAddress = model.StreetAddress;
        org.Suite = model.Suite;
        org.City = model.City;
        org.State = model.State;
        org.Zip = model.Zip;
        org.Country = model.Country;
        db.Entry(org).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("CompanyInfo", "Organization");
    }
    return View();
}

2 个答案:

答案 0 :(得分:0)

在ASP.NET MVC中拥有一个ViewModel的唯一真正问题是,当您将其发回时,您不知道View已填充了哪些属性,因为正如您所说,您只是在各种视图上填充它们的子集。理想情况下你应该遵循的模式是每个View都有一个ViewModel(并且正如这篇文章的第一条评论所说,你应该将它传递给你的View,而不是你的模型)。

您使用内置注释验证肯定会发现有问题,因为每个View都会有不同的验证要求,因为它们处理的是实体的不同部分。

另外我想提一下,当我们在ASP.NET MVC中讨论ViewModel时,我们不是在基于XAML的UI框架中讨论与ViewModel相同的东西,甚至是像Knockout这样的JavaScript库。或者Angular 2.这些ViewModel可以在视图甚至应用程序之间共享,因为它们存在于客户端上:这就是可以在消费时针对View执行业务逻辑。

答案 1 :(得分:0)

您的问题是,CompanyInfo(ManageMessageId? message)操作方法返回db.Organizations.Single(x => x.OrgId == member.OrgId),我打赌的类型为Organization(或其他),但肯定不是类型CompanyInfoViewModel

您应该做的是在CompanyInfoViewModel对象数据中的第一个方法中构建org

在这种情况下,使用视图模型是可以接受的,尽管在这种情况下它们通常被称为DTO。 (数据传输对象)我通常为____ViewModel个动作命名View____EditModel动作命名Edit等等。他们不是只是< / em> ViewModel个对象,它们也用于其他操作。 (有时我们有真正复杂的事情需要他们自己的DTO。)