2

我正在尝试为仅部分编辑的模型找到使用 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 }; }
    }
}

名称字段是可编辑的。父字段仅供参考,不应更新。因此,它是使用 DisplayFor 呈现的。

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

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

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

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

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

4

2 回答 2

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)

Since details like your Mother are un-editable then they're not really part of the "Edit" model, so I'd box like that away and try to let something else take care of them.

于 2013-03-29T16:55:03.347 回答
1

If you aren't going to update the Parent field, then it really doesn't matter if it's a hidden or not, since you won't update it on post.

I would use the hidden in this case, just make sure not to update that field.

于 2013-03-29T18:36:06.240 回答