MVC模型绑定复杂对象

时间:2013-12-29 13:14:45

标签: asp.net-mvc razor binding model action

我已经在网上阅读并实现了许多答案,但没有运气..

我的模型看起来像这样:

public class CampaignModel : BaseModel
{
    .
    .
    public List<TreeItem> Countries { get; set; }
    .
    .
}

在视图中我有:

@foreach (var country in Model.Countries.Select((value,i)=> new {i, value}))
{
<input type="checkbox" name="campaign.Countries[@country.i].Id" value="@country.value.Id" @(country.value.IsSelected ? "checked=\"checked\"" : "") />
}

在我的行动中:

[HttpPost]
public ActionResult UpdateTargeting(CampaignModel campaign)
{
    return View(campaign);
}

但'国家'属性结果为空。

我做错了什么? 谢谢

2 个答案:

答案 0 :(得分:3)

首先,我认为您需要在名称属性中使用Model而不是campaign,如下所示:

name="@Model.Countries[@country.i].Id"

现在,您的foreach循环将生成如下的html代码:

<input type="checkbox" name="1" value="1"/>
<input type="checkbox" name="2" value="2" checked=""checked""/>

使用上面的代码,模型绑定将不起作用,这就是您在提交表单时获得空值的原因。您需要以下内容:

<input id="Countries_0__IsSelected" name="Countries[0].IsSelected" type="checkbox" value="true"/>
<input name="Countries[0].IsSelected" type="hidden" value="false"/>
<input checked="checked" id="Countries_1__IsSelected" name="Countries[1].IsSelected" type="checkbox" value="true"/>
<input name="Countries[1].IsSelected" type="hidden" value="false"/>

所以我建议您使用Razor语法,如下所示:

foreach (var country in Model.Countries.Select((value,i)=> new {i, value}))
{
      @Html.CheckBoxFor(m => m.Countries[@country.i].IsSelected )    
}

答案 1 :(得分:0)

我最后添加了2个隐藏字段来识别确切的复选框。

TreeItem像这样摇晃:

public class TreeItem
{
    public int Id { get; set; }
    public string Title { get; set; }
    public bool IsSelected { get; set; }
    public List<TreeItem> Leafes { get; set; }

    public TreeItem() { }

    public TreeItem(int id, string title, bool selected = false, List<TreeItem> leafes = null)
    {
        Id = id;
        Title = title;
        IsSelected = selected;
        Leafes = leafes;
    }
}

完整的解决方案看起来像这样(我展示了一个2级层次结构):

<ul id="devicesList">
    @foreach (var brand in Model.DeviceBrands.Select((value, i) => new { i, value }))
    { 
                    <li>
                        @Html.CheckBoxFor(m => m.DeviceBrands[@brand.i].IsSelected)
                        @Html.HiddenFor(m => m.DeviceBrands[@brand.i].Id)
                        @Html.HiddenFor(m => m.DeviceBrands[@brand.i].Title)
                        <label><b>@brand.value.Title</b></label>
                        <ul>
                            @foreach (var deviceModel in brand.value.Leafes.Select((value, j) => new { j, value }))
                            {
                                <li>
                                    @Html.CheckBoxFor(m => m.DeviceBrands[@brand.i].Leafes[@deviceModel.j].IsSelected)
                                    @Html.HiddenFor(m => m.DeviceBrands[@brand.i].Leafes[@deviceModel.j].Id)
                                    @Html.HiddenFor(m => m.DeviceBrands[@brand.i].Leafes[@deviceModel.j].Title)
                                    <label>@deviceModel.value.Title</label>
                                </li>
                            }
                        </ul>
                    </li>
    }
</ul>

谢谢林!