Razor MVC模型正在丢失Save动作的数据

时间:2011-03-25 17:12:29

标签: asp.net-mvc razor

我有一个使用TextBoxFor的文本框,其中包含数据。

我有一个模型的ID和一些其他基本数据,但直接在视图中显示为标签。

当我提交表单时,只有文本框字段包含模型上的数据,其他所有内容都为空,包括Id。这意味着它不会保存到数据库中。

什么会导致所有字段与文本框分开?

3 个答案:

答案 0 :(得分:16)

这是网络的工作方式,只有表单元素与表单一起提交,标签不是表单元素。

这里经常发生的是你:

  1. 呈现包含ID和文本框的隐藏字段(Html.Hidden / Html.HiddenFor
  2. 接受控制器操作中的更改(作为参数或对象)
  3. 从您的存储库/数据库
  4. 中水合Id表示的对象的实例
  5. 将更改应用于水合实例
  6. 验证对象的状态并更新您的存储库/数据库(或您计划用它做的任何事情)
  7. 由于发布的数据类由于缺少属性(例如标记为[Required])而经常“无效”,因此创建仅具有更改属性的新类(称为“命令模型“)。此类可以拥有自己的验证属性,因此不会影响表单验证。

答案 1 :(得分:6)

仅将输入发回服务器。如果您希望基于页面上的数据填充模型,则它们必须位于输入(或URL的一部分)中。标签元素中的数据不会使用表单发布到服务器(这是标准的HTML表单行为)。通常,您使用隐藏字段回发不可编辑的模型数据,或者只是引用模型ID并从数据库重新填充,更新可编辑属性(如下所示)。

示例:

 @(using Html.BeginForm( new { id = Model.ID } ))
 {
       <p>
           <label>Fixed Property:</label>
           @Model.SomeFixedProperty
       </p>
       <p>
          @Html.LabelFor( m => m.EditableProperty )
          @Html.TextBoxFor( m => m.EditableProperty )
       </p>
}

控制器

[HttpPost]
public ActionResult Foo( int id, string editableProperty )
{
    var model = repo.GetById( id );
    model.EditableProperty = editableProperty;
    repo.Save();
    return View( model );
}

答案 2 :(得分:0)

虽然我同意@RichardSzalay,但另一种方法是将未更改的属性标记为未修改。

假设您有一个包含以下属性的模型:Id,Name,Email。而且你不想改变电子邮件。

public ActionResult ChangeName([Bind(Include="Id,Name")] User model)
{
    // ...
    db.Entry(model).State = EntityState.Modified;
    db.Entry(model).Property(m => m.Email).IsModified = false;
    db.SaveChanges();
    // ...
}

缺点是由于模型中缺少字段,您可能会遇到验证问题。