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

Posted

技术标签:

【中文标题】如何从 HttpPost Create 操作方法中知道选中的复选框?【英文标题】:How to know the selected checkboxes from within the HttpPost Create action method? 【发布时间】:2016-12-22 00:30:40 【问题描述】:

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 操作方法中知道选中的复选框?

【问题讨论】:

请说的更具体一些,你想知道控制器Action里面Post包含多少个复选框吗? @OscarOrtiz:我想将提交的数据保存为新学生。但我不知道如何检查哪些复选框。 【参考方案1】:

您可以使用编辑器模板来做到这一点。

首先,为课程选择创建一个新类并更新您的视图模型以包含该类的集合。

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 的目录。在那里创建一个新的剃须刀文件并命名为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);

现在在您的主视图中 (Create.cshtml),它是 StudentCourseVM 的强类型,在 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 属性值。用户在 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

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

有时您希望在页面加载时预先选择一些复选框(例如:对于您的编辑屏幕,您希望将已保存的课程显示为已选中)。为此,您只需在 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);

上面的代码会预先选中 SwiftIOS 的复选框。

【讨论】:

您能否详细解释一下“您不需要将实体模型中的所有属性复制并粘贴到视图模型中。视图模型只需要视图绝对需要的那些属性。”?如果我们不这样做,意味着什么?先感谢您。它会增加渲染的 HTML 输出的文件大小并浪费带宽? 如果你的视图要添加一个客户的姓名字段,在视图模型中只需要姓名字段即可。根据需要添加属性(按视图)。

以上是关于如何从 HttpPost Create 操作方法中知道选中的复选框?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 HttpPost 方法从 Ok(对象值)中获取值

如何将模型作为参数传递给 ASP.NET MVC 中的 [HttpPost] ActionMethod?

如何从电流控制器中获取价值?

如何正确使用ValidateAntiForgeryToken?

C#常用的HttpGet HttpPost HttpDownload方法类

[HttpPost] ASP.NET中有啥作用???