[英]Nested models are lost after post action using MVC3
我正在尝试创建RoomType记录。 每个RoomType都有一个RoomTypeInfos集合,它们是每种语言的描述。 然后,每个RoomTypeInfo都与语言记录相关联。
因此,要创建RoomType,我会为每种语言预加载一个RoomTypeInfo对象。
采取行动:
//
// GET: /RoomType/Create/IdHotel
[HttpGet]
public ActionResult Create(int id)
{
List<Language> _Languages = __roomTypeRepository.GetLanguages().ToList<Language>();
RoomType roomType = new RoomType { IdHotel = id };
roomType.RoomTypeInfos = new System.Data.Linq.EntitySet<RoomTypeInfo>();
foreach (Language Language in _Languages)
{
roomType.RoomTypeInfos.Add(new RoomTypeInfo { Language = Language });
}
return View(roomType);
}
发布动作:
//
// POST: /RoomType/Create/
[HttpPost]
public ActionResult Create(RoomType roomType)
{
try
{
if (ModelState.IsValid)
{
__roomTypeRepository.InsertRoomType(roomType);
return RedirectToAction("Index", new { id = roomType.IdHotel });
}
else
{
return View(roomType);
}
}
catch
{
return View(roomType);
}
}
因此,如果在post操作中模型无效或捕获到异常,则在视图中的@ Model.Language.Name中出现错误,因为Language现在为null。
RoomTypeInfo编辑器模板的代码:
@model DataAccess.RoomTypeInfo
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.IdRoomType)
@Html.HiddenFor(model => model.IdLanguage)
<fieldset>
<legend>@Model.Language.Name</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Descripcion)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.Descripcion, new { Class = "wysiwyg" })
@Html.ValidationMessageFor(model => model.Descripcion)
</div>
</fieldset>
和RoomType编辑器模板:
@model DataAccess.RoomType
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.IdHotel)
<h3>
Información Básica
</h3>
<div class="editor-field">
@Html.EditorFor(model => model.RoomTypeInfos)
@Html.ValidationMessageFor(model => model.RoomTypeInfos)
</div>
我通过查询语言表并将其再次设置到每个RoomTypeInfo.Language来修复它,但是如果感觉像是一种解决方法。
在这种情况下,最佳做法是什么?
我们使用Steve Sanderson为此编写的BeginCollectionItem HTML帮助程序 。 在局部视图中,我们将所有输入字段包装在@using(Html.BeginCollectionItem("RoomTypeInfos"))
。
在后台,这会更改输入元素名称和ID,以便默认模型绑定器识别它们并将其添加到根视图模型(在您的情况下为RoomType)。
代码示例:
@model DataAccess.RoomTypeInfo
@using (Html.BeginCollectionItem("RoomTypeInfos"))
{
Html.HiddenFor(model => model.Id)
Html.HiddenFor(model => model.IdRoomType)
Html.HiddenFor(model => model.IdLanguage)
<fieldset>
<legend>@Model.Language.Name</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Descripcion)
</div>
<div class="editor-field">
@Html.TextAreaFor(model => model.Descripcion, new { Class = "wysiwyg" })
@Html.ValidationMessageFor(model => model.Descripcion)
</div>
</fieldset>
}
此外,如果要确保POST后语言不为空,则应将其添加为隐藏字段:
@Html.HiddenFor(m => m.Language.Name)
这样,它就可以通过默认的模型绑定器绑定到模型。 如果您不通过HTTP POST(在某种输入字段中)发送数据,那么您的POST操作方法必须在返回模型和视图之前重新填充它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.