Подтвердить что ты не робот

MV3 Duplicate Query String Значения для CheckBox (true, false for boolean)

Я создал довольно прямолинейную страницу с флажком:

@using (Html.BeginForm("MyController", "MyAction", FormMethod.Get))
{
  @Html.CheckBoxFor(x => x.MyCheckBox)
  <input type="submit" value="Go!" />      
}

URL-адрес заполняется значением MyCheckBox дважды!? Таким образом:

MyAction?MyCheckBox=true&MyCheckBox=false

Он только дублирует значение, если флажок установлен в true. Если установлено значение false, оно будет отображаться только один раз в строке запроса.

Приведенный выше код упрощен, так как у меня есть несколько выпадающих списков и текстовое поле в форме, которая работает нормально. Я не думаю, что есть что-то необычное в коде, который я упустил из этого вопроса.

У кого-то была аналогичная проблема с дублирующимися параметрами строки запроса?

4b9b3361

Ответ 1

Это поведение осуществляется с помощью элемента управления флажком. Стандартный флажок checkbox HTML не имеет значения, если он не установлен. Это неинтуитивно. Вместо этого элемент управления ASP.Net имеет два элемента: стандартный элемент управления, который является видимым, а также скрытый элемент управления со значением "False".

Поэтому, если флажок не установлен, будет передано одно значение: False.
Если он установлен, будут два значения: True и False. Поэтому для проверки правильности кода необходимо использовать следующий код:

bool checkboxChecked = Request.QueryString["MyCheckBox"].Contains("True");

Ответ 2

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

MVC Html.CheckBox(...) и Html.CheckBoxFor(...) генерируют дополнительный ввод "type = hidden" с тем же идентификатором, что и элемент управления флажком, что приводит к дублирующим параметрам URL. Я обошел эту проблему, просто включив требуемую маркировку следующим образом:

@if(checkTrue){
    <input type="checkbox" id="MyCheckBox" name="MyCheckbox" checked="checked">
}else{
    <input type="checkbox" id="MyCheckBox" name="MyCheckbox">
}

Было бы лучше обернуто в помощнике для использования вместо кода MVC, чтобы проверка значения была инкапсулирована.

Как часть моего приложения, контроллер поддерживает наборы параметров запроса, используя как инъекцию формы, так и вставку ссылок с помощью помощников, чтобы сохранить состояние (например, элементов подкачки/фильтрации) при навигации по одному и тому же диапазону. В результате этой функции элемент флажка всегда возвращается к false, если используются стандартные помощники MVC. Хорошо, что я заметил и не тратил много времени на эту ошибку.

Ответ 3

В моей модели у меня была коллекция флажков вроде:

public class PrerequisitesViewModel
{
    public List<StudentPrerequisiteStatusViewModel> PrerequisiteStatuses { get; set; }
}

public class StudentPrerequisiteStatusViewModel
{
    public long Id { get; set; }

    public string Name { get; set; }

    public bool IsSelected { get; set; }
}

Чтобы все было правильно привязано, мне пришлось фактически преобразовать значения из строки запроса и проанализировать их вручную с помощью следующего кода:

// fix for how MVC binds checkboxes... it send "true,false" instead of just true, so we need to just get the true
for (int i = 0; i < model.PrerequisiteStatuses.Count(); i++)
{
    model.PrerequisiteStatuses[i].IsSelected = bool.Parse((Request.QueryString[$"PrerequisiteStatuses[{i}].IsSelected"] ?? "false").Split(',')[0]);
}

Увы, это работает, но я не могу поверить, что это необходимо в MVC! Надеюсь, кто-то еще знает о лучшем решении.