如何让我的基于列表编辑模板绑定正确的POST操作?(How do I make my list ba

2019-08-08 03:06发布

我有一个模型, ApplicantBranchList ,被用作一个更大的模型的属性如下:

[Display(Name = "Where would you want to work?")]
public ApplicantBranchList PreferedBranches { get; set; }

ApplicantBranchList

public class ApplicantBranchList : ViewModel
{
    public ApplicantBranchItem HeaderItem { get; set; }
    public ApplicantBranchList()
    {
        HeaderItem = new ApplicantBranchItem();
    }
    public void MapFromEntityList(IEnumerable<ApplicantBranch> applicantBranches)
    {
        var service = new BranchService(DbContext);
        var selectedIds = applicantBranches.Select(b => b.BranchId);
        Items = service.ReadBranches()
                       .Where(i => !i.IsDeleted)
                       .Select(p => new ApplicantBranchItem { BranchName = p.Name, WillWorkAt = selectedIds.Contains(p.Id) });
    }
    public IEnumerable<ApplicantBranchItem> Items { get; set; }
}

ApplicantBranchList有自己的编辑模板,并在每个项目内编辑模板ApplicantBranchList

查看/共享/ EditorTemplates / ApplicantBranchList.cshtml:

@model Comair.RI.UI.Models.ApplicantBranchList
<table>
    <tr>
        <th style="display: none;"></th>
        <th>
            @Html.DisplayNameFor(model => model.HeaderItem.BranchName)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.HeaderItem.WillWorkAt)
        </th>
    </tr>
    @foreach (var item in Model.Items)
    {
        @Html.EditorFor(m => item)
    }
</table>

查看/共享/ EditorTemplates / ApplicantBranchItem.cshtml:

@model Comair.RI.UI.Models.ApplicantBranchItem
<tr>
    <td style="display: none;">
        @Html.HiddenFor(m => m.BranchId)
    </td>
    <td>
        @Html.DisplayFor(m => m.BranchName)
    </td>
    <td>
        @Html.EditorFor(m => m.WillWorkAt)
    </td>
</tr>

这个编辑器中正确呈现在视图中,但在后的行动:

public ActionResult Create(ApplicantProfileModel model)
{
    if (ModelState.IsValid)
    {
        var branches = model.PreferedBranches;

PreferedBranches.Itemsnull

我究竟做错了什么?

Answer 1:

问题是,ASP.NET无法弄清楚如何绑定到Model.Items财产。

要修复它取代:

public IEnumerable<ApplicantBranchItem> Items { get; set; }

有了这个:

public List<ApplicantBranchItem> Items { get; set; }

而不是:

@foreach (var item in Model.Items)
{
   @Html.EditorFor(m => item)
}

使用这一个:

@for (var i = 0; i < Model.Items.Count; i++)
{
   @Html.EditorFor(model => model.Items[i]) // binding works only with items which are accessed by indexer
}


Answer 2:

随着MVC和编辑模板,你并不需要手动通过列表中移动和呼叫@HTMLEditorFor。

这样做:

@Html.EditorFor(model => model.Items)

是相同的:

@for (var i = 0; i < Model.Items.Count; i++)
{
   @Html.EditorFor(model => model.Items[i]) // binding works only with items which are accessed by indexer
}

MVC将通过您的项目处理的迭代和每个项目一旦生成你的编辑模板。 正如评论指出模板必须命名一样的模型。 此外,你的模型定义应该是你的模型的奇异表现,而不是IEnumerable类型。 最后,正如在评论中指出,如果你设置的呼叫模板名称参数@ Html.EditorFor(),您将不会有自动迭代的好处超过您的收藏。 您将需要手动循环如上面所示。



文章来源: How do I make my list based editor template bind properly for a POST action?