如何使用ViewModel

时间:2011-09-26 18:07:41

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

好的,经过一些研究后,我无法理解“viewmodel的事情”。

我没有找到任何文章解释我使用ViewModel的步骤与简单地将实体作为模型传递给View相比。 使用纯实体时,它非常简单:

如果要创建新条目,只需显示视图即可。如果是发布,验证,请添加(x)和voilá!编辑时,填充对象并将其发送到视图。发布,验证,更改状态并保存。这里不是秘密。

但我无法创建和编辑ViewModels。有人可以帮我吗?

简而言之,我有这个POCO:

public class Vessel
{
    public int Id { get; set; }

    [Required]
    public string Name { get; set; }

    public int ShipownerId { get; set; }
    public virtual Shipowner Shipowner { get; set; }
}

public class Shipowner
{
    public int Id { get; set; }

    public string Name { get; set; }


    public virtual ICollection<Vessel> Vessels { get; set; }
}

这个观点:

@model INTREPWEB.Models.VesselCreateViewModel
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
    <fieldset>
        <legend>Vessel</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Vessel.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Vessel.Name)
            @Html.ValidationMessageFor(model => model.Vessel.Name)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.Vessel.ShipownerId, Model.Shipowners, String.Empty)
            @Html.ValidationMessageFor(model => model.Vessel.Name)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

我已经创建了这个ViewModel:

public class VesselCreateViewModel
{
    public Vessel Vessel { get; set; }

    public SelectList Shipowners { get; set; }

    public VesselCreateViewModel()
    {
        using (INTREPDB db = new INTREPDB())
        {
            var list = db.Shipowners.ToList()
                .Select(x => new SelectListItem
                {
                    Text = x.Name,
                    Value = x.Id.ToString()
                });
            Shipowners = new SelectList(list, "Value", "Text");
        }
    }

    public VesselCreateViewModel(int id)
    {
        using (INTREPDB db = new INTREPDB())
        {

            Vessel = db.Vessels.Find(id);

            var list = db.Shipowners.ToList()
                .Select(x => new SelectListItem
                {
                    Text = x.Name,
                    Value = x.Id.ToString()
                });
            Shipowners = new SelectList(list, "Value", "Text");
        }
    }
}

如您所见,它会自动为View添加一个集合以显示DropDown菜单。我能够通过与仅使用模型相同的方式创建新的船只。但是在编辑这个东西时无法弄清楚我做错了什么。

这是错误的POST编辑方法:

    [HttpPost]
    public ActionResult Edit(VesselCreateViewModel vm)
    {
        if (ModelState.IsValid)
        {
            db.Entry(vm.Vessel).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(vm);
    }

我该怎么做才能拯救这个小怪物?

3 个答案:

答案 0 :(得分:1)

正如您所看到的,您只在此代码中使用ViewModel的Model部分。这是典型的恕我直言,所以你将ViewModel传递给View,但只在Edit-Postback中绑定模型。

然后,如果必须,您可以根据更改的模型轻松地重新创建视图模型。

BTW:在这种情况下,IMO ViewModel是一个糟糕的名字。如果我听到ViewModel,我会想到MVVM,但是这种情况下,viewmodel只是某种静态类型的View-Helper而且应该没有行为。

答案 1 :(得分:1)

Viewmodel从史蒂夫·森德森的书中摘录一下

MVC also uses the term view model, but refers to a simple model class that is used only to pass data from 
a controller to a view. We differentiate between view models and domain models, which are sophisticated 
representations of data, operations, and rules.

如果要保存视图模型,可以使用automapper

答案 2 :(得分:1)

我猜你应该像使用VesselCreateViewModel构造函数一样在Using块中包装db调用。

您最终可以使用ViewModel中的命令来保存,编辑或删除数据,并将此命令绑定到视图上的按钮或其他控件。

我会推荐两本关于MVVM的好书,你会找到很好的例子,也很容易理解它们。

  

使用Windows®PresentationFoundation构建企业应用程序   和模型视图ViewModel模式

     

Pro WPF和Silverlight MVVM - 有效的应用程序开发   模型视图查看模型