问题
I've read and implemented many answers here and around the web but had no luck..
My model looks something like this:
public class CampaignModel : BaseModel
{
.
.
public List<TreeItem> Countries { get; set; }
.
.
}
In the view i have:
@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\"" : "") />
}
At the action I have:
[HttpPost]
public ActionResult UpdateTargeting(CampaignModel campaign)
{
return View(campaign);
}
But the 'Countries' property turns out null.
What am I doing wrong? Thank you
回答1:
First I think you need to use Model
instead of campaign
in the name attributes, like below:
name="@Model.Countries[@country.i].Id"
And right now your foreach
loop will generate the html code like below:
<input type="checkbox" name="1" value="1"/>
<input type="checkbox" name="2" value="2" checked=""checked""/>
With above code, the model binding will not work, that's why you got null values when you submitted the form. You need something like below:
<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"/>
So I suggest you to use Razor
syntax, like below:
foreach (var country in Model.Countries.Select((value,i)=> new {i, value}))
{
@Html.CheckBoxFor(m => m.Countries[@country.i].IsSelected )
}
回答2:
I ended up adding 2 more hidden fields to identify the exact checkbox.
The TreeItem lolks like this:
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;
}
}
The full solution looks like this (I demonstrate a a 2 level hierarchy):
<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>
Thanks Lin!
来源:https://stackoverflow.com/questions/20825520/mvc-model-binding-of-complex-objects