Поле выбора не заполняется при просмотре после того, как недействительное состояние модели - PullRequest
0 голосов
/ 05 мая 2018

Я создаю новый основной проект MVC .net, чтобы люди могли использовать его для подачи предложений для презентации на конференции.

Для формы подачи предложения я использую модель привязки (модель представления AKA) для привязки ввода пользователя в форме.

Вот часть кода для связующего класса модели:

public class BaseSubmissionBindingModel
{

    public BaseSubmissionBindingModel(){

    }

    [Required]
    public int ConferenceId { get; set; }

    [Required]
    [StringLength(250)]
    [Display(Name = "Title")]
    public string SubmissionTitle { get; set; }

    [Required]
    [StringLength(1000)]
    [Display(Name = "Abstract")]
    public string SubmissionAbstract { get; set; }


    public IEnumerable<SelectListItem> SubmissionCategoryItems { get; set; }

    [Required]
    [Display(Name = "Select the Submission Category ")]
    public string SelectedSubmissionCategory { get; set; }

}

Обратите внимание на поле SubmissionCategoryItems - это поле используется для заполнения раскрывающегося элемента формы выбора в представлении. Данные для этого элемента управления поступают из запроса к базе данных, и какие категории отправки отображаются в зависимости от значения идентификатора конференции.

В классе контроллера я получаю категории отправки для идентификатора конференции и создаю List<SelectListItem> submissionCategoryItems с объектом SelectListItem для каждой категории отправки.

Затем я создаю объект BaseSubmissionBindingModel и назначаю submissionCategoryItems для BaseSubmissionBindingModel IEnumerable<SelectListItem> SubmissionCategoryItems.

Затем контроллер возвращает View (baseSubmissionBindingModel).

Страница просмотра для ввода пользователя отображается правильно, а в поле выбора «Выбрать категорию отправки» указаны правильные параметры для каждой категории представления.

Ниже приведен HTML-код формы создания заявки

<div class="form-group">
    <label asp-for="SelectedSubmissionCategory"></label>
    <select asp-for="SelectedSubmissionCategory" asp-items="@Model.SubmissionCategoryItems">
         <option value="" selected>--select--</option>
    </select>
    <span asp-validation-for="SelectedSubmissionCategory"></span>
</div>

Моя проблема возникает, если пользователь не вводит в форму обязательное значение, а затем нажимает кнопку отправки формы.

В моем классе контроллера есть метод CreateSubmission, который вызывается, когда пользователь нажимает кнопку отправки в форме

public IActionResult CreateSubmission(BaseSubmissionBindingModel baseSubmissionBindingModel) {

        if (! ModelState.IsValid) {

            return View("Index", baseSubmissionBindingModel);
        }

        Log.Information("Submission data provided is " + baseSubmissionBindingModel.ToString());

        return View("Success", baseSubmissionBindingModel);

    }

Если пользователь отправляет форму без предоставления всех необходимых данных, то состояние модели недействительно. Начальное представление возвращается пользователю вместе с сообщениями об ошибках валидации.

Однако поле выбора для категории отправки больше не имеет опций для категорий отправки, извлеченных из базы данных. Таким образом, пользователь больше не может выбирать категорию представления.

Как я могу убедиться, что в поле выбора категории отправки все еще есть элементы опций, если пользователь не смог изначально предоставить все необходимые данные, но все еще отправил форму? Спасибо за помощь.

Bruce

1 Ответ

0 голосов
/ 05 мая 2018

При сбое проверки состояния модели вы возвращаетесь к тому же представлению, в котором есть помощник тега SELECT. Ваш помощник по тегу select использует свойство SubmissionCategoryItems переданной модели представления в качестве исходной коллекции для построения параметров элемента SELECT. Http не имеет состояния . Для вашего второго вызова (вызов отправки формы) он не имеет никакого представления о том, что вы делали в предыдущем вызове (вы настраивали эти элементы сбора в вызове действия GET). Поэтому вам нужно устанавливать значение свойства коллекции каждый раз, когда вы возвращаетесь к представлению, которое использует эту коллекцию для построения элемента select.

public IActionResult CreateSubmission(BaseSubmissionBindingModel model) 
{
    if (! ModelState.IsValid)
    {
        // Set the collection property value again
        model.SubmissionCategoryItems = GetCategoryItems(); 
        return View("Index", model);
    }
    //to do : do some thing useful
    Log.Information("Submission data " + baseSubmissionBindingModel.ToString());
    return View("Success", model);    
}

private List<SelectListItem> GetCategoryItems()
{
    var items = new List<SelectListItem>();

    // TO DO : I hard coded 2 items. You can replace it with items from your database

    items.Add(new SelectListItem() { Value = "1", Text = "Seattle" });
    items.Add(new SelectListItem() { Value = "2", Text = "Detroit" });

    return items;
}
...