asp.net-mvc-3mvc-editor-templateseditortemplates

IEnumerable property with MVC3 EditorTemplate


Similar to this post IEnumerable model property in an ASP.NET MVC 3 Editor Template, I have

Model

public class Student
{
    public int StudentId { get; set; }
    public string StudentName{ get; set; }

    //FYI..Its virtual because of EF relationship
   public virtual ICollection<Class> Classes{ get; set; }
}
public class Class
{
    public int ClassId { get; set; }
    public string ClassName{ get; set; }     
}

View - EditStudent

@model Student

@Html.TextBoxFor(m => m.StudentName)

//I get the error for following..see below
@Html.EditorFor(m => m.Classes);

Student/EditorTemplates/Class

@model Class

<div>
    @*checkbox here*@
    @Html.LabelFor(x => x.ClassName)
</div>

Controller

public ActionResult EditStudent(int id)
{
    ViewBag.Classes = repository.GetClasses();
    Student student = repository.GetStudent(id);

    return View("EditStudent", student);
}
  1. Error in View on statement @Html.EditorFor(m => m.Classes); is..

    The model item passes into the dictionary is of type 'System.Collections.Generic.HashSet`1[Class]', but this dictionary required a model item of type 'Class'.

  2. Basically, what I am trying to achieve is to display the list of all classes available with a checkbox next to it ( I have not reached to that part of code yet). Then check all classes to a student is enrolled and allow to change the selections.

    • How do I display the list of checkboxes with the given Model.
    • Should I bind my EditorTemplate with ViewBag.Classes (How?) or ?
    • I need to get selected checkbox values in Post ActionMethod as well.
    • I read some posts those suggest to create CheckBoxListHelper, but it should be possible to do with EditorTemplate as I need to display a simple list.

Please suggest. Thanks.


Solution

  • Okay, I figured it out. Thanks to very precise post here

    How to provide an EditorTemplate for IEnumerable<MyModel>?

    First, I renamed the EditorTemplate to StudentClass - not sure if this has anything to do with binding or not, but I did.

    Second, modified EditorTemplate to bind with IEnumerable

    @model IEnumerable<Class>
    var checked = "";
    @foreach (Class class in ViewBag.Classes)
    {
        if (Model != null)
        {
            Class class = Model.FirstOrDefault(c => c.ClassId.Equals(class.ClassId));
            if (class != null)
            {
                checked = "checked=checked";
            }
        }
        <input type="checkbox" name="Classes" value="@class.ClassId" @checked />
        @class.ClassName
    }
    

    And I call the template with name

    @Html.EditorFor(m => m.Classes, "StudentClass"); 
    

    Now in controller's Post method I can get the array of Classes (name of checkboxes).