Search code examples
asp.net-mvcmodelsasp.net-mvc-partialview

Composite model not binding mvc 3


I have created two models, Student and School and a composite model, StudentSchool. I am using two different partiel views to create one the Student and the other the School. However, in my controller, I am getting null values for both the Student and School. Below is my code:

Student:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace LayoutProject.Models
{
    public class Student
    {
        public int studentID { get; set; }
        public String firstname { get; set; }
        public String lastname { get; set; }
        public int year { get; set; }
    }
}

School:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace LayoutProject.Models
{
    public class School
    {
        public int schoolID { get; set; }
        public String name { get; set; }
        public String add { get; set; }
    }
}

Composite model, StudentSchool:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;


namespace LayoutProject.Models
{
    public class StudentSchool
    {
        public Student student { get; set; }
        public School school { get; set; }
    }
}

PartielViewStudent:

   @model LayoutProject.Models.Student

<h4>Student</h4>

            @Html.LabelFor(d=>d.studentID) : @Html.TextBoxFor(d=>d.studentID)

            <br />
            @Html.LabelFor(d=>d.firstname) : @Html.TextBoxFor(d=>d.firstname)

            <br />
            @Html.LabelFor(d=>d.lastname) : @Html.TextBoxFor(d=>d.lastname)

            <br />
            @Html.LabelFor(d=>d.year) : @Html.TextBoxFor(d=>d.year)

            <br />

PartialViewSchool:

    @model LayoutProject.Models.School

<h4>School</h4>


        @Html.LabelFor(d=>d.schoolID) : @Html.TextBoxFor(d=>d.schoolID)

        <br />
        @Html.LabelFor(d=>d.name) : @Html.TextBoxFor(d=>d.name)

        <br />
        @Html.LabelFor(d=>d.add) : @Html.TextBoxFor(d=>d.add)

        <br />

The View:

    @{
    ViewBag.Title = "StudentSchool";
}


<h2>StudentSchool</h2>
<form action="/Home/CreateStudentSchools" method="post">

    @using (Html.BeginForm())
    {


        @Html.Partial("_PartialViewStudent")

        @Html.Partial("_PartialViewSchool")
    }

    <input id="createSD" type="submit" value="Submit"/>
</form>

The controller:

 [HttpPost]
        public ActionResult CreateStudentSchools(StudentSchool ss)
        {
            return View("CreateStudentSchool");
        }

Any idea what I might be missing here? Been with this since 4 days.


Solution

  • Move you 'partial' views into the /Views/Shared/EditorTemplates folder and rename them to Student.cshtml and School.cshtml respectively (to match the names of the classes). Then in the main view use

    @using (Html.BeginForm())
    {
        @Html.EditorFor(m => m.Student)
        @Html.EditorFor(m => m.School)
    }
    

    The inputs your generating will now contain the correct name attribute for binding to your view model, for example name="Student.studentID" instead of the current name="studentID"

    Note: As an alternative, you can pass the HtmlFieldPrefix to a Partial as indicated in this answer.