MVC 3 - Binding to a Complex Type with a List type property
I have a following view model and it will be used by a search control that I'm working on.
public class SearchViewModel
{
public SearchViewModel()
{
SearchLocation = new SearchLocationViewModel();
SearchCategories = new SearchCategoriesViewModel();
}
public SearchLocationViewModel SearchLocation { get; set; }
public SearchCategoriesViewModel SearchCategories { get; set; }
}
Now, SearchCategoriesViewModel has the following structure:
public class SearchCategoriesViewModel
{
[Display(Name = "Categories")]
public IList<SearchCategoryViewModel> Categories { get; set; }
public SearchCategoriesViewModel()
{
Categories = new List<SearchCategoryViewModel>();
}
}
And, finally, search category view model has the following structure:
public class SearchCategoryViewModel
{
[Required]
[Display(Name="Id")]
public int Id { get; set; }
[Display(Name="Name")]
public String Name { get; set; }
public bool IsSelected { get; set; }
}
When I submit a search request, the SearchLocationViewModel comes through with submitted parameters, however, SearchCategoriesViewModel comes through empty (not null).
Below is an editor template for my开发者_运维问答 SearchCategoryViewModel:
@model MyDLL.WebUI.Models.SearchCategoriesViewModel
@foreach (var c in Model.Categories)
{
@Html.Label(c.Name);
@Html.CheckBox(c.Name,c.IsSelected);
}
I use the following view to generate the search controls:
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<div id="search">
@Html.EditorFor(m => m.SearchCategories, "SearchCategory")
@Html.EditorFor(m => m.SearchLocation, "SearchLocation")
</div>
<p>
<input type="submit" value="Create" />
</p>
}
I end up with the following markup:
<h2>Search</h2>
<form action="/Settings/Search" method="post">
<label for="SearchCategories_Professional">Professional</label>
<input id="SearchCategories_Professional" name="SearchCategories.Professional" type="checkbox" value="true" />
<input name="SearchCategories.Professional" type="hidden" value="false" />
<label for="SearchCategories_Associate">Associate</label><input id="SearchCategories_Associate" name="SearchCategories.Associate" type="checkbox" value="true" />
<input name="SearchCategories.Associate" type="hidden" value="false" />
<p>
<input type="submit" value="Create" />
</p>
</form>
I suspect that the parameters are not coming through because generated markup is wrong. Did any of you try generating partial views from complex objects? I don't want to pass IEnumerable, I would rather have it encapsulated in a seperate class so that I can extend/remove it in the future if needed.
Thank you
Because you have a static list, you can quickly hack your way to creating markup which will be bound correctly:
@model MyDLL.WebUI.Models.SearchCategoriesViewModel
@{
var i = 0;
}
@foreach (var c in Model.Categories)
{
@Html.Hidden("Categories[" + i.ToString() + "].Id", c.Id);
@Html.Hidden("Categories[" + i.ToString() + "].Name", c.Name);
@Html.Label(c.Name);
@Html.CheckBox("Categories[" + i.ToString() + "].IsSelected",c.IsSelected);
}
This is a quick and ugly solution. However, I would suggest that you reconsider how you are generating the markup in your partial view.
精彩评论