我正在尝试创建一个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来修复它,但如果感觉像是一种解决方法。
在这种情况下,最佳做法是什么?
答案 0 :(得分:2)
我们使用BeginCollectionItem HTML helper authored by Steve Sanderson来实现此目的。在局部视图中,我们将所有输入字段包装在@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操作方法将必须重新填充它,然后才能返回模型&amp;视图。