0

How do I bind such a complex model with multiple layers that contain multiple objects? Right now I pass the model to the view - (populating a form / a check box tree) and I would like the exact model back (SubjectSelectionModel) but it's not binding correctly.

Could anyone elaborate on the process I need to take in order to bind these correctly in my view?

View Model:

public class SubjectSelectionModel
{
    public IList<Subject> Subjects { get; set; }
}

Subject Class:

public class Subject
{
    public String Name { get; set; }
    public IList<Bin> Bins { get; set; }

    public Subject()
    {

    }

    public Subject(IList<Course> courses)
    {

    }
}

Bin Class:

public class Bin 
{
    public Subject Subject { get; set; }
    public int Amount { get; set; }

    public IList<Foo> Foos { get; set; }
}

Foo Class:

public class Foo
{
    public int Number { get; set; }
}

2 Answers 2

5

This is where Editor Templates come in handy. Rather than messing around with this, you can use simple editor templates to handle all the grunt work for you.

You would create several templates in ~/Views/Shared/EditorTemplates, and then in your primary view it should look like this:

View.cshtml

@model SubjectSelectionModel
@using(Html.BeginForm()) {
    @EditorFor(m => m.Subjects)
    <input type="submit" />
}

Subject.cshtml

@model Subject
@Html.EditorFor(m => m.Name)
@Html.EditorFor(m => m.Bins)

Bin.cshtml (I assume you don't want to render Subject, this would be an infinite loop)

@model Bin
@Html.EditorFor(m => m.Amount)
@Html.EditorFor(m => m.Foos)

Foo.cshtml

@model Foo
@Html.EditorFor(m => m.Number)

Obviously, you may want to change the html formatting to whatever you want, but that's essentially it.

Sign up to request clarification or add additional context in comments.

2 Comments

Clearly I had a brain fart. Much better answer for nested stuff like this!
Oh thank you! I had this exactly but I also had the Subject reference which gave me the infinite loop.
1

You need a for loop for the objects so MVC can bind using the index in the collection.

Example:

for (int subjectIndex = 0; subjectIndex < Model.Subjects.Count; subjectIndex++) {
    @Html.TextBoxFor(x => x.Subjects[subjectIndex].Name)

    for (int binIndex = 0; binIndex < Model.Subjects.Bins.Count; binIndex++) {
        @Html.TextBoxFor(x => x.Subjects[subjectIndex].Bins[binIndex].Amount)
    }
}

..etc.

I gave a similar response to a similar question, here: Generating an MVC RadioButton list in a loop

3 Comments

What about the Bin referring back to the subject? And you forgot to include [subjectIndex] after Model.Subjects.(here).Bins.Count
@Nate - you wouldn't render the Bin subject, otherwise it would just create an infinite loop. Subject renders Bin, bin renders subject, which renders bin, which renders subject.. etc..
I had something similar to this before the Editor Templates - Thanks for your help though!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.