完成未受约束的MVC模型属性的最佳实践?

时间:2013-03-29 15:36:50

标签: asp.net-mvc-4 model-binding

我正在尝试找到将MVC用于仅部分编辑的模型的最佳方法。

下面是一个简单的例子。

模型

using System.ComponentModel.DataAnnotations;
public class SimpleModel
{
    public int Id { get; set; }
    public string Parent { get; set; }
    [Required]
    public string Name { get; set; }
}

查看

using System.ComponentModel.DataAnnotations;
public class SimpleModel
{
    public int Id { get; set; }
    public string Parent { get; set; }
    [Required]
    public string Name { get; set; }
}

控制器

using System.Web.Mvc;

public class SimpleController : Controller
{
    public ActionResult Edit(int id)
    { return View(Get(id)); }

    [HttpPost]
    public ActionResult Edit(int id, SimpleModel model)
    {
        if (model.Name.StartsWith("Child")) //Some test that is not done client-side.
        {
            Save(model);
            //Get the saved data freshly.
            //model = Get(id);
        }
        else
        {
            ModelState.AddModelError("", "Name should start with 'Child'");
        }
        //Is this the way to set the Parent property?
        //var savedModel = Get(id);
        //model.Parent = savedModel.Parent;
        return View(model);
    }

    //Mock a database.
    SimpleModel savedModel;

    private void Save(SimpleModel model)
    { savedModel = new SimpleModel() { Id = model.Id, Name = model.Name }; }

    private SimpleModel Get(int id)
    {
        if (savedModel == null)
        { return new SimpleModel() { Id = id, Parent = "Father", Name = "Child " + id.ToString() }; }
        else
        { return new SimpleModel() { Id = savedModel.Id, Parent = "Father", Name = savedModel.Name }; }
    }
}

“名称”字段可编辑。 Parent字段仅供参考,不应更新。因此,它使用DisplayFor进行渲染。

发帖后,我收到一个模型,其属性Parent设置为null。这没问题,因为它不会被保存。但是,当我只是将接收的模型返回到视图时,将不再显示父字段。当模型有效时,我可以轻松地从数据库中获取它,从而获得Parent字段的值。

当模型无效时,我想允许用户更正输入并尝试再次保存。在那里,我应该使用输入的模型值,但是也应该显示显示的值。

实际上,还有许多字段需要显示以供参考,通常来自不同的数据库实体,而不是正在编辑的字段。

我已经看到过将字段作为隐藏字段传递给视图的建议,但我觉得非常不愿意从客户端读取不应更新的数据。

有没有更优雅的方法来手动将这些值复制到模型中或将它们作为隐藏字段传递?

2 个答案:

答案 0 :(得分:1)

如何将这些不可编辑的属性提供给另一个模型并让它来处理这些属性呢?

查看模型

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

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

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

    public PersonDetailsModel DetailsModel { get; set; }
}

详情模型

public class PersonDetailsModel
{
    public string Mother { get; set; }
    public string Father { get; set; }

    public PersonDetailsModel() { }

    public PersonDetailsModel(int personId)
    {
        // pull required model data from databases
        var db = DBParentContext;
        Mother = db.Parent.Where(m => m.ChildId == personId)
        Father = db.Parent.Where(m => m.ChildId == personId)
    }
}

<强>控制器

public class PersonController : Controller
{
    [HttpPost]
    public ActionResult Edit(PersonViewModel viewModel)
    {
        viewModel.DetailsModel = new PersonDetailsModel(viewModel.Id)

        if (ModelState.IsValid) {
            // ~
        }
        return View(viewModel)
    }
}

查看

@model PersonViewModel

@Html.DisplayFor(m => m.DetailsModel.Mother)
@Html.DisplayFor(m => m.DetailsModel.Father)
@Html.TextBoxFor(m => m.FirstName)
@Html.TextBoxFor(m => m.LastName)

由于像你母亲这样的细节是不可编辑的,所以它们并不是“编辑”模型的真正组成部分,所以我会把它当作盒子并试着让别的东西照顾它们。

答案 1 :(得分:1)

如果您不打算更新父字段,那么它是否隐藏无关紧要,因为您不会在帖子上更新它。

我会在这种情况下使用隐藏,只是确保不要更新该字段。