IEnumerable property with MVC3 EditorTemplate

2019-07-25 17:18发布

问题:

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.

回答1:

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).