【问题标题】:MVC Model binding of complex objects复杂对象的MVC模型绑定
【发布时间】:2013-12-29 13:14:45
【问题描述】:

我已经在这里和网络上阅读并实施了许多答案,但没有运气..

我的模型看起来像这样:

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);
}

但 'Countries' 属性结果为空。

我做错了什么? 谢谢

【问题讨论】:

  • 复选框名称中不需要campaign. 前缀。
  • 你能提供 TreeItem 类的细节吗,我认为这没有被初始化。尝试在构造函数中这样做

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


【解决方案1】:

首先我认为您需要在名称属性中使用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 )    
}

【讨论】:

  • 谢谢林,你写的帮助我想出了下面的解决方案!
  • 其他尝试过的人请注意:不适用于国家/地区的 IEnumerable 或 ICollection,仅适用于列表或数组
【解决方案2】:

我最终添加了 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>

谢谢林!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-28
    • 2017-07-16
    • 2014-01-25
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多