0

I am working on the Contoso University example with MVC and one of my projects is to learn how to send a collection of models in a post. I am growing the example online to instead of taking a value and adding it to a collection, I am wanting to take two values and add that object (model) to the collection to accomplish a one-to-many relationship. In the view I have added two boxes with a + when you hit it, it will add two more boxes, allowing the user to have as many course name / course number pairs as he or she chooses. Notice that in the create an instructor post, the method takes an Instructor and an array of selectedCourses (which is just check boxes).

 [HttpPost]
 [ValidateAntiForgeryToken]
 public ActionResult Create([Bind(Include = "LastName,FirstMidName,HireDate,OfficeAssignment")]Instructor instructor, string[] selectedCourses)
        {
            if (selectedCourses != null)
            {
                instructor.Courses = new List<Course>();
                foreach (var course in selectedCourses)
                {
                    var courseToAdd = db.Courses.Find(int.Parse(course));
                    instructor.Courses.Add(courseToAdd);
                }
            }
            if (ModelState.IsValid)
            {
                db.Instructors.Add(instructor);
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            PopulateAssignedCourseData(instructor);
            return View(instructor);
        }

I am at a loss on how to do this one properly. My idea was to say...

 [HttpPost]
 [ValidateAntiForgeryToken]
 public ActionResult Create([Bind(Include = "LastName,FirstMidName,HireDate,OfficeAssignment")]Instructor instructor, string[] selectedCoursesNames string[] selectedCoursesNumbers )
        {
            if (selectedCourses != null)
            {
                instructor.Courses = new List<Course>();
                foreach (var course in selectedCoursesNames)
                {
                    instructor.Courses.Add(new courseToAdd()
                    {
                        name = selectedCoursNames[course],
                        number = selectedCoursNumbers[course]
                    });
                    }
                }
                if (ModelState.IsValid)
                {
                    db.Instructors.Add(instructor);
                    db.SaveChanges();
                    return RedirectToAction("Index");
                }
                PopulateAssignedCourseData(instructor);
                return View(instructor);
            }

Obviously this is not the best way to do it, the better solution would be to post an array of objects then run a loop that adds each one to the instructor.

I have two problems though, I do not know how to post a list of models and how does the model on my view know that that section is going to post an array of models in that one section and make that one section an array of models? Does it need to be a partial view? can I most this one method both models? I cannot seem to find many good resources on this one online and it has put me at a halt on doing this one for a few days.

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/ This article made decent reference on what I am wanting to do, but they hard coded the indexes and that doesn't keep it dynamic length... I guess I could make a JavaScript code that increments it when the + sign is pressed, but it doesn't seem right still. This still does not solve the problem of how to post both models at the same time with the same method.

I do know the methods on using a viewModel to place multiple enumerable models in a view, but I do not understand how to bind two different models in one form.

Travis Tubbs
  • 827
  • 1
  • 14
  • 32

1 Answers1

0

Just make a ViewModel.

public class Instructor{
      public string LastName;
      public string FirstMidName;
      public DateTime HireDate;
      public string OfficeAssignment;
      public List<Course> course;
}

public class Course{
      public string name;
      public int number;
}

and then

public ActionResult Create(Instructor instructor){}

so you just have to create an Instructor object in your ajax function

Chinito
  • 1,085
  • 1
  • 9
  • 11