Как узнать выбранные флажки из метода действия HttpPost Create?

У меня есть отношения "многие ко многим" между Student и Course. Набор связывающих объектов: 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; }
}

ViewModels

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?


person Let Me Be Your Lost Disciple    schedule 15.08.2016    source источник
comment
Пожалуйста, будьте более конкретными, вы хотите знать, сколько флажков содержит сообщение внутри действия контроллера?   -  person Oscar Ortiz    schedule 15.08.2016
comment
@OscarOrtiz: я хочу сохранить отправленные данные как новый студент. Но я не знаю, как получить, какие флажки отмечены.   -  person Let Me Be Your Lost Disciple    schedule 15.08.2016


Ответы (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, используйте вспомогательный метод EditorFor для свойства SelectedCourses.

@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. Курсы, выбранные пользователем в пользовательском интерфейсе, будут иметь значение 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
}

введите здесь описание изображения

Предварительная установка некоторых флажков при загрузке страницы

Иногда вы хотите предварительно установить некоторые флажки при загрузке страницы (например, для вашего экрана редактирования вы хотите показать уже сохраненные курсы как отмеченные). Для этого вам просто нужно установить для свойства IsSelected соответствующего объекта SelectedCourse значение true в методе действия GET.

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);
}

Приведенный выше код предварительно установит флажки для Swift и IOS.

person Shyju    schedule 15.08.2016
comment
Не могли бы вы подробнее объяснить, что вам не нужно копировать и вставлять все свойства из вашей модели объекта в модель представления. Модель представления нуждается только в тех свойствах, которые абсолютно необходимы представлению. Что будет, если мы этого не сделаем? Заранее спасибо. Это увеличит размер файла отображаемого HTML-файла и приведет к потере пропускной способности? - person Let Me Be Your Lost Disciple; 17.08.2016
comment
Если ваше представление должно добавить поле имени клиента, просто добавьте в модель представления только поле имени. добавьте свойства по мере необходимости (по представлению). - person Shyju; 17.08.2016