【发布时间】:2015-08-26 15:01:06
【问题描述】:
我有一个 ASP.NET MVC 应用程序,它通过采购订单跟踪我们公司的供应商。每个 PO 评级都分配了一个类型。每种类型可以有多个评级部分,每个评级部分可以有多个类别。这些类看起来像这样:
public class RatingModel{
/*Fields for the purchase order*/
public List<RatingSectionModel> RatingSections { get; set; }
}
public class RatingSectionModel {
/*Fields for the Rating section*/
public List<RatingCategoryModel > Categories { get; set; }
}
public class RatingCategoryModel {
/*Fields for the category*/
}
在我的项目中,我尝试使用找到的修改后的 BeginCollectionItem here。 cshtml是:
_RatingModel.cshtml:
@model VendorRating.Models.RatingModel
@Html.HiddenFor(model => model.VendorId)
@Html.HiddenFor(model => model.VendorName)
@Html.HiddenFor(model => model.AwardDate)
@Html.HiddenFor(model => model.AwardValue)
@Html.HiddenFor(model => model.CloseDate)
@Html.HiddenFor(model => model.FinalValue)
@Html.HiddenFor(model => model.ServiceRep)
@Html.HiddenFor(model => model.PoId)
<div style="display:table;margin-bottom:5px;">
<div style="display:table-row">
<div style="display:table-cell;vertical-align:top;">
@Html.LabelFor(model => model.TypeId)
</div>
<div style="display:table-cell;vertical-align:top;">
@Html.DropDownListFor(model => model.TypeId, Model.Types)
</div>
</div>
</div>
<table>
<tr>
<td class="table-header">@Html.LabelFor(model => model.PoId, htmlAttributes: new { @class = "control-label" })</td>
<td class="table-header">@Html.LabelFor(model => model.VendorName, htmlAttributes: new { @class = "control-label" })</td>
<td class="table-header">@Html.LabelFor(model => model.AwardDate, htmlAttributes: new { @class = "control-label" })</td>
<td class="table-header">@Html.LabelFor(model => model.AwardValue, htmlAttributes: new { @class = "control-label" })</td>
</tr>
<tr>
<td>@Html.DisplayFor(model => model.PoId, new { htmlAttributes = new { @class = "form-control" } })</td>
<td>@Html.DisplayFor(model => model.VendorName, new { htmlAttributes = new { @class = "form-control" } })</td>
<td>@Html.DisplayFor(model => model.AwardDate, new { htmlAttributes = new { @class = "form-control" } })</td>
<td>@Html.DisplayFor(model => model.AwardValue, new { htmlAttributes = new { @class = "form-control" } })</td>
</tr>
<tr>
<td class="table-header">@Html.LabelFor(model => model.CloseDate, htmlAttributes: new { @class = "control-label" })</td>
<td class="table-header" ">@Html.LabelFor(model => model.FinalValue, htmlAttributes: new { @class = "control-label" })</td>
<td class="table-header" ">@Html.LabelFor(model => model.ServiceRep, htmlAttributes: new { @class = "control-label" })</td>
</tr>
<tr>
<td>@Html.DisplayFor(model => model.CloseDate, new { htmlAttributes = new { @class = "form-control" } })</td>
<td>@Html.DisplayFor(model => model.FinalValue, new { htmlAttributes = new { @class = "form-control" } })</td>
<td>@Html.DisplayFor(model => model.ServiceRep, new { htmlAttributes = new { @class = "form-control" } })</td>
</tr>
</table>
<div id="sections">
@{
if(Model.Sections != null) {
@Html.EditorFor(model => model.Sections)
}
}
RatingSectionModel.cshtml:
@model List<VendorRating.Models.RatingSectionModel>
@{
var id = "";
foreach(VendorRating.Models.RatingSectionModel sectionModel in Model) {
using(Html.BeginCollectionItem("Sections", out id)) {
<fieldset style="margin-top:10px;">
<legend style="font-weight:bold;">
@sectionModel.SectionName
@Html.HiddenFor(model => sectionModel.SectionId)
</legend>
<div style="display:table;width:100%">
@foreach(VendorRating.Models.RatingCategoryModel c in sectionModel.RatingCategories) {
@Html.EditorFor(cat => c);
}
<div style="display:table-row;width:100%">
<div style="display:table-cell;width:70%"></div>
<div style="display:table-cell;text-align:right;width:10%"></div>
<div style="display:table-cell;text-align:right;width:10%">Total</div>
<div style="display:table-cell;text-align:right;width:10%;"><div data-section-total="@sectionModel.SectionId" style="width:50%;border-bottom:solid 1px lightgray;text-align:right;"></div></div>
</div>
</div>
</fieldset>
<script>
function changeTotals() {
var totalScore = 0;
$('#poForm').find('*[data-section-score="@sectionModel.SectionId"]').each(function () {
var val = parseFloat($(this).text());
if (!isNaN(val)) {
totalScore = totalScore + val;
}
});
$('#poForm').find('*[data-section-total="@sectionModel.SectionId"]').text(totalScore);
}
</script>
}
}
}
字段生成正确,但是当我检查表单时,每个字段的名称是 Sections[sectionid here].sectionModel.FieldName。在提交表单时,插入名称中的 sectionModel 会阻止它与 Sections 集合正确绑定。适当数量的部分被添加到集合中,但它们的所有属性都是空的。我确定我在这里设置了一些错误,但我不知道它可能是什么。
【问题讨论】:
-
id值不用于绑定 - 它们不提交给服务器。namehtml 属性是Request.Form集合中的键,绑定使用它们。 -
谢谢。我是说名字。现在已经更正了。
-
完美!将 foreach 更改为 for 并删除 BeginCollectionItem,它可以完美运行。 @DanielGpeReyes,如果您将其作为答案提交,我很乐意接受并投票。
-
尽管接受了答案,但真正的问题是您不理解
EditorTemplate。RatingSectionModel.cshtml应该是@model RatingSectionModel(不是List<T>)。EditorFor()接受IEnumerable<T>并根据集合中每个项目的模板呈现 html。此外,您无需先检查null。它只是@Html.EditorFor(m => m.RatingSections)(我认为Sections是一个错字) -
感谢您提供的信息。我以前看到过,但是当我尝试以这种方式编写代码时,它抛出了一个异常,指出该模型不是 IEnumerable。我确定我做错了什么,但在这个特定的项目上,我没有时间回去探索它。
标签: c# asp.net asp.net-mvc asp.net-mvc-4 razor