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, оно будет отображаться только один раз в строке запроса.
Приведенный выше код упрощен, так как у меня есть несколько выпадающих списков и текстовое поле в форме, которая работает нормально. Я не думаю, что есть что-то необычное в коде, который я упустил из этого вопроса.
У кого-то была аналогичная проблема с дублирующимися параметрами строки запроса?
Ответы
Ответ 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! Надеюсь, кто-то еще знает о лучшем решении.