c# - 如何使用 View 模型

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

好吧,经过一番研究,我无法理解“viewmodel 的东西”。

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

如果创建一个新条目,只显示 View 。如果是 post,验证,执行 Add(x) 和瞧!编辑时,填充一个对象并将其发送到 View 。发布时,验证,更改状态并保存。这里没有 secret 。

但我无法创建和编辑 ViewModel。有人可以帮我解决这个问题吗?

简而言之,我有这个 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; }
}

这个 View :

@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 的集合以显示下拉菜单。我能够通过与仅使用模型相同的方式创建新容器。但是在编辑这个东西时无法弄清楚我做错了什么。

这是错误的 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);
    }

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

最佳答案

如您所见,您在此代码中仅使用了 ViewModel 的模型部分。这是典型的恕我直言,因此您将 ViewModel 传递给 View ,但仅在您的 Edit-Postback 中绑定(bind)模型。

然后,如果需要,您可以根据更改后的模型轻松地重新创建 View 模型。

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

关于c# - 如何使用 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7559296/

相关文章:

c# - 将 LINQ-to-Entities 查询组合成单个查询

c# - 无法访问已处置的对象。套接字 C#

c# - 从客户端应用程序连接到 SQL Azure 数据库

c# - CSharp - 将变量名称存储在另一个变量中,以便可以在给定对象上动态调用它

c# - 确保另一条记录尚未包含相同的字段值

asp.net-mvc - 从 GIT 部署 Azure 网站时出错

c# - 在不使用 foreach 循环的 C# 中填充列表中的列表。更好的方法?

c# - 创建一个带有日期的新 .txt 文件,C#

c# - 使用自定义逻辑在 MVC 中对大量数据进行分页

c# - 升级到 EF 6 现在出现 LINQ 错误