每当我提交表单时,控制器操作中的ViewModel对象都具有ViewModel中每个字段的空(或默认)值。 ViewModel对象本身不为null,但其所有值都为null或default(对于整数为0,对于DateTimes为1/1/0001 12:00:00 AM等)。
在谷歌搜索此问题并看到各种建议后,我确认了以下内容:
为什么ViewModel值未正确发布?
这就是我所拥有的:
PaneViewModel
public class PaneViewModel
{
public ViewModel NewItem { get; set; }
public DataTableViewModel DataTable { get; set; }
}
视图模型
[Table("TableName")]
public class ViewModel
{
[Key]
[Column(Order = 0)]
[DisplayName("ID")]
public int ID { get; set; }
[Key]
[Column(Order = 1)]
[DisplayName("AnotherID")]
public int AnotherID { get; set; }
[Key]
[Column(Order = 2)]
[DisplayName("Some Date")]
public DateTime SomeDate { get; set; }
[Required]
[DisplayName("Another Date")]
public DateTime AnotherDate { get; set; }
[DisplayName("A Third Date")]
public DateTime? AThirdDate { get; set; }
}
查看
@using (Ajax.BeginForm("AddItem", "Controller", new AjaxOptions
{
UpdateTargetId = "add-item-section",
LoadingElementId = "loading-image",
HttpMethod = "POST",
}))
{
<section id="add-item-section">
<table>
<tr>
<th>@Html.LabelFor(m => m.NewItem.SomeDate)</th>
<th>@Html.LabelFor(m => m.NewItem.AnotherDate)</th>
<th>@Html.LabelFor(m => m.NewItem.AThirdDate)</th>
<th></th>
</tr>
@Html.EditorFor(m => m.NewItem, "ViewModelEditorTemplate")
</table>
</section>
}
查看模型编辑器模板
@model ViewModel
<tr>
<td>@Html.EditorFor(m => m.SomeDate)</td>
<td>@Html.EditorFor(m => m.AnotherDate)</td>
<td>@Html.EditorFor(m => m.AThirdDate)</td>
<td><button type="submit" class="btn btn-info">Add</button></td>
</tr>
@Html.HiddenFor(m => m.ID)
@Html.HiddenFor(m => m.AnotherID)
控制器
[HttpPost]
public ActionResult AddItem(ViewModel item)
{
// Breakpoint set here (code removed because it's irrelevant to this issue).
}
答案 0 :(得分:1)
Model绑定器将尝试将这些名称NewItem.ID
等与ViewModel
类的属性进行匹配。不幸的是,Model绑定器在绑定到您的对象时不会自动知道删除NewItem
前言。
如果接受ParentViewModel
类型的对象(或者调用初始模型的任何对象),这应该允许Model绑定器使用表单中的属性正确初始化ParentViewModel.NewItem
。
[HttpPost]
public ActionResult AddItem(ParentViewModel item)
{
ViewModel newItem = item.NewItem;// <-- bound using the name to properties mapping
}
如果不希望这样,您可以随时实现自定义模型绑定器,但这可能对此问题有点过分。
编辑
Stephen还指出了使用binding prefix明确告诉ModelBinder
在属性之前预期NewItem
的替代方法。
[HttpPost]
public ActionResult AddItem([Bind(Prefix="NewItem")]ViewModel item)
{
//item should be bound using the properties correctly
}
根据您的偏好,这些解决方案中的任何一个都适合您。
答案 1 :(得分:-1)
从我所看到的,你忘了为ajax调用实例化Form。为此,请使用帮助程序Ajax.BeginForm,如下例所示。
@using (Ajax.BeginForm("MyAction", "MyController",
new AjaxOptions {
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "target"}))
{
<tr>
<td>@Html.EditorFor(m => m.SomeDate)</td>
<td>@Html.EditorFor(m => m.AnotherDate)</td>
<td>@Html.EditorFor(m => m.AThirdDate)</td>
<td><button type="submit" class="btn btn-info">Add</button></td>
</tr>
@Html.HiddenFor(m => m.ID)
@Html.HiddenFor(m => m.AnotherID)
}
有关Ajax帮助程序的更多信息,请访问http://www.blackbeltcoder.com/Articles/script/using-ajax-beginform-with-asp-net-mvc