Model binding a collection property with a partial view

.net, asp.net-mvc, asp.net-mvc-4, c#, model-binding

Solution

As you do not want to use an `EditorTemplate` for `Bar`, a solution of your scenario could be:

Change the @model type of the '_EditBars' partial view to `Foo` and view should be like:

@model Foo

@if (Model.Bars != null)
{
    for (int i = 0; i < Model.Bars.Count; i++)
     {
         @Html.EditorFor(m => Model.Bars[i].Baz)
     }
}

(It would be better to change the partial view's name to `'_EditFooBars'`)

Hope this helps.

Problem

Suppose I have a model like this: ``` public class Foo { public List<Bar> Bars { get; set; } public string Comment { get; set; } } public class Bar { public int Baz { get; set; } } ``` And I want a view of `Foo` that lets users edit `Bar` items. But with a catch: I want the `Bar` editing to be handled by a partial view. ``` @model Web.ViewModels.Foo @using(Html.BeginForm()) { @Html.Partial("_EditBars", Model.Bars) @Html.TextAreaFor(m => m.Comment) ... } ``` The `_EditBars` partial view looks something like: ``` @model List<Web.ViewModels.Bar> @for (int i = 0; i < Model.Count; i++) { @Html.EditorFor(m => Model[i].Baz) } ``` I want this to model bind to my action, which looks something like: ``` [HttpPost] public ActionResult Edit(Foo foo) { // Do stuff } ``` Unfortunately, this is the data that I'm posting, which doesn't model bind the `Bars` property: ``` [1].Baz=10&[0].Baz=5&Comment=bla ``` It makes sense that this doesn't work, because it's missing the `Bars` prefix. If I understand correctly, I need it to be this: ``` Bars[1].Baz=10&Bars[0].Baz=5&Comment=bla ``` So, I tried this approach: ``` @Html.Partial( "_EditBars", Model.Bars, new ViewDataDictionary(ViewData) { TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "Bars" } }) ``` But that's not working either. With that, I'm getting: ``` Bars.[1].Baz=10&Bars.[0].Baz=5&Comment=bla ``` I assume that that isn't working because of the extra period (`Bars.[1]` vs. `Bars[1]`). Is there anything I can do to get the result that I desire? Note: This is a major oversimplification of my actual situation. I recognize that with something this simple, the best approach would probably be to make an `EditorTemplate` for `Bar` and loop through using `EditorFor` in my view. If possible, I'd like to avoid this solution.

Original source

Related problems