如何从 HttpPost Create 操作方法中知道选中的复选框?

How to know the selected checkboxes from within the HttpPost Create action method?

我在 StudentCourse 之间存在多对多关系。链接实体集是Enrollment。为了简单起见,都定义如下

型号

public class Course
{
    public int Id { get; set; }
    public string Title { get; set; }

    public virtual ICollection<Enrollment> Enrollments { get; set; }
}

public class Enrollment
{
    public int Id { get; set; }
    public int StudentId { get; set; }
    public int CourseId { get; set; }

    public virtual Student Student { get; set; }
    public virtual Course Course { get; set; }
}

public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Enrollment> Enrollments { get; set; }
}

视图模型

public class StudentCourseVM
{
    public Student Student { get; set; }
    public IEnumerable<Course> SelectedCourses { get; set; }
    public IEnumerable<Course> AvailableCourses { get; set; }
}

控制器

    public IActionResult Create()
    {
        var availableCourses = context.Courses;
        return View(new StudentCourseVM { AvailableCourses = availableCourses });
    }


    [HttpPost]
    public async Task<IActionResult> Create(StudentCourseVM sc)
    {
        if (ModelState.IsValid)
        {
            // What should I do here?
            // ======================
            await context.SaveChangesAsync();
            return RedirectToAction("Index");
        }
        return View(sc);
    }

观看次数

@model MasterDetails.ViewModels.StudentCourseVM
<form asp-action="Create">
    <div>
        <label asp-for="@Model.Student.Name"></label>
        <input asp-for="@Model.Student.Name" />
    </div>
    <div>
        <label asp-for="@Model.Student.Enrollments"></label><br />
        @foreach (var course in Model.AvailableCourses)
        {
            <input type="checkbox" name="@course.Title" id="@course.Id" /> @course.Title <br />
        }
    </div>
    <input type="submit" value="Create" />
</form>

问题

如何从 HttpPost Create 操作方法中知道选中的复选框?

您可以使用 编辑器模板 来执行此操作。

首先,为课程 selection 创建一个新的 class 并更新您的视图模型以收集该 class。

public class SelectedCourse
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}

public class StudentCourseVM
{
    public int StudentId { set; get; }       
    public IEnumerable<SelectedCourse> SelectedCourses { get; set; }
}

您不需要将实体模型中的所有属性复制并粘贴到视图模型中。 视图模型只需要视图绝对需要的那些属性。我假设您想将课程分配给特定学生

现在转到 ~/Views/YourControllerName 并创建一个名为 EditorTemplates 的目录。在那里创建一个新的 razor 文件并命名为 SelectedCource.cshtml

将此代码粘贴到新文件

@model SelectedCourse
<label>@Model.Name</label>
<input asp-for="IsSelected"/>
<input type="hidden" asp-for="Id" />

现在在您的 GET 操作中,创建视图模型的对象,加载 SelectedCourses 集合并将其发送到视图。

public IActionResult Create()
{
    // I hard coded the student id and the courses here.
    // you may replace it with real data.
    var vm = new StudentCourseVM { StudentId = 12 }; 
    //Assuming we are assigning courses to the student with id 12
    vm.SelectedCourses = new List<SelectedCourse>()
    {
        new SelectedCourse {Id = 1, Name = "CSS"},
        new SelectedCourse {Id = 2, Name = "Swift"},
        new SelectedCourse {Id = 3, Name = "IOS"},
        new SelectedCourse {Id = 4, Name = "Java"}
    };
    return View(vm);
}

现在在 StudentCourseVM 的强类型主视图 (Create.cshtml) 中,在 SelectedCourses 属性.

上使用 EditorFor 辅助方法
@model StudentCourseVM
<form asp-action="Create">   
    @Html.EditorFor(f=>f.SelectedCourses)
    <input type="hidden" asp-for="StudentId"/>
    <input type="submit"/>
</form>

编辑器模板将为 SelectedCourses 集合中的每一项执行编辑器模板文件中的代码。因此,用户可以看到课程名称和复选框。

在您的 HttpPost 操作方法中,您可以使用相同的视图模型作为参数。提交表单后,您可以循环遍历 SelectedCourses 属性 中的项目,检查 IsSelected 属性 值。 select 在 ui 中编辑的课程将具有 true 值。

[HttpPost]
public IActionResult Create(StudentCourseVM model)
{
    var studentId = model.StudentId; 
    foreach (var modelSelectedCourse in model.SelectedCourses)
    {
        if (modelSelectedCourse.IsSelected)
        {
            //this one is selected. Save to db
        }
    }
    // to do : Return something
}

在页面加载时预先select勾选一些复选框

有时您希望在页面加载时预先 select 一些复选框(例如:对于您的编辑屏幕,您希望将已保存的课程显示为已选中)。为此,您只需在 GET 操作方法中将相应 SelectedCourse 对象的 IsSelected 属性 设置为 true。

public IActionResult Edit(int id)
{
    // I hard coded the student id and the courses here.
    // you may replace it with real data.
    var vm = new StudentCourseVM { StudentId = id }; 
    //Assuming we are assigning courses to the student with id 12
    vm.SelectedCourses = new List<SelectedCourse>()
    {
        new SelectedCourse {Id = 1, Name = "CSS"},
        new SelectedCourse {Id = 2, Name = "Swift", IsSelected = true },
        new SelectedCourse {Id = 3, Name = "IOS", IsSelected = true },
        new SelectedCourse {Id = 4, Name = "Java"}
    };
    return View(vm);
}

上面的代码将预先 select SwiftIOS 的复选框。