Как обрабатывать флажки в формах ASP.NET MVC?

Внимание: этот вопрос старше девяти лет!

Ваш лучший вариант – искать новые вопросы или искать ответы ниже в поисках вашей конкретной версии MVC, так как многие ответы здесь устарели.

Если вы найдете ответ, который работает для вашей версии, убедитесь, что ответ содержит версию MVC, которую вы используете.
(Оригинальный вопрос начинается ниже)


Мне это кажется немного странным, но, насколько я могу судить, так оно и есть.

У меня есть набор объектов, и я хочу, чтобы пользователи выбирали один или несколько из них. Это говорит мне «форму с флажками». У моих объектов нет понятия «выбранный» (они являются рудиментарным POCO, образованным десериализацией вызова wcf). Итак, я делаю следующее:

public class SampleObject{ public Guid Id {get;set;} public string Name {get;set;} } 

В представлении:

        

И в controllerе это единственный способ увидеть, какие объекты проверял пользователь:

 public ActionResult ThisLooksWeird(FormCollection result) { var winnars = from x in result.AllKeys where result[x] != "false" select x; // yadda } 

В первую очередь это причудливо, а во-вторых, для тех элементов, которые пользователь проверил, FormCollection перечисляет его значение как «true false», а не просто true.

Очевидно, что я что-то упускаю. Я думаю, что это построено с учетом того, что объекты в коллекции, которые действуют в форме html, обновляются с помощью UpdateModel() или через ModelBinder.

Но мои объекты не настроены для этого; означает ли это, что это единственный способ? Есть ли другой способ сделать это?

    22 Solutions collect form web for “Как обрабатывать флажки в формах ASP.NET MVC?”

    Html.CheckBox делает что-то странное – если вы просматриваете исходный код на результирующей странице, вы увидите, что рядом с каждым флажком создается , в котором объясняются значения «истинные ложные», которые вы видите для каждого элемента формы.

    Попробуйте это, что определенно работает на ASP.NET MVC Beta, потому что я только что попробовал.

    Поместите это в представление вместо использования Html.CheckBox ():

     < % using (Html.BeginForm("ShowData", "Home")) { %> < % foreach (var o in ViewData.Model) { %>  < %= o.Name %> < %}%>  < %}%> 

    Все флажки вызывается selectedObjects , а value каждого из них – GUID соответствующего объекта.

    Затем отправьте сообщение на следующее действие controllerа (или что-то подобное, что делает что-то полезное вместо Response.Write ())

     public ActionResult ShowData(Guid[] selectedObjects) { foreach (Guid guid in selectedObjects) { Response.Write(guid.ToString()); } Response.End(); return (new EmptyResult()); } 

    В этом примере будут записываться только GUID из отмеченных вами полей; ASP.NET MVC отображает значения GUID выбранных флажков в параметр Guid[] selectedObjects для вас и даже анализирует строки из коллекции Request.Form в объекты GUID, которые я считаю довольно приятными.

    HtmlHelper добавляет скрытый ввод, чтобы уведомить controller о статусе Unchecked. Итак, чтобы иметь правильный проверенный статус:

     bool bChecked = form[key].Contains("true"); 

    Если вам интересно, ПОЧЕМУ они помещают скрытое поле с тем же именем, что и флажок, причина такова:

    Комментарий от исходного кода MVCBetaSource \ MVC \ src \ MvcFutures \ Mvc \ ButtonsAndLinkExtensions.cs

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

    Я думаю, что за кулисами им нужно знать это для привязки к параметрам в методах действий controllerа. Тогда вы могли бы иметь логическое состояние tri-state, предположительно (связанное с нулевым параметром bool). Я не пробовал, но я надеюсь, что это так.

    Вы также должны использовать потому что тогда люди могут нажимать на текст ярлыка, а также на флажок. Его также легче стилизовать и, по крайней мере, в IE, он будет выделен при входе в элементы управления страницы.

     < %= Html.CheckBox("cbNewColors", true) %> 

    Это не просто «о, я могу это сделать». Это значительно улучшает работу пользователя. Даже если не все пользователи знают, что они могут щелкнуть по ярлыку, многие будут.

    Я удивлен, что ни один из этих ответов не использовал встроенные функции MVC для этого.

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

    Вы просто получите новый файл в папке EditorTemplate, который выглядит так:

     @model SampleObject @Html.CheckBoxFor(m => m.IsChecked) @Html.HiddenFor(m => m.Id) @Html.LabelFor(m => m.IsChecked, Model.Id) 

    в вашем фактическом представлении не будет необходимости цитировать это, просто 1 строка кода:

     @Html.EditorFor(x => ViewData.Model) 

    Посетите мой пост в блоге для получения более подробной информации.

    Вот что я делаю.

    Посмотреть:

    
     

    controller:

    var checkBox = Request.Form["applyChanges"]; if (checkBox == "on") { ... }
    var checkBox = Request.Form["applyChanges"]; if (checkBox == "on") { ... } 

    Я обнаружил, что методы Html. * Helper не так полезны в некоторых случаях, и что мне было лучше делать это в простом старом HTML. Это один из них, другой, который приходит на ум, – это радиокнопки.

    Изменить: это на Preview 5, очевидно YMMV между версиями.

    Кажется, что они предпочитают читать только первое значение, поэтому это «истинно», когда флажок установлен, и «false», когда включено только скрытое значение. Это легко получить с помощью кода:

     model.Property = collection["ElementId"].ToLower().StartsWith("true"); 

    @ Дилан Битти Отличная находка !!! Я благодарю вас. Для дальнейшего расширения этот метод также отлично работает с подходом View Model. MVC настолько classный, он достаточно умен, чтобы привязать массив Guids к свойству с тем же именем объекта Model, связанного с представлением. Пример:

    ViewModel:

     public class SampleViewModel { public IList SampleObjectList { get; set; } public Guid[] SelectedObjectIds { get; set; } public class SampleObject { public Guid Id { get; set; } public string Name { get; set; } } } 

    Посмотреть:

      

    Sample View

    < % using (Html.BeginForm()) %> < %{%> < % foreach (var item in Model.SampleObjectList) { %> < % } %>
    Checked Object Name
    < %= Html.Encode(item.Name)%>
    < %}%>

    controller:

      [AcceptVerbs(HttpVerbs.Get)] public ActionResult SampleView(Guid id) { //Object to pass any input objects to the View Model Builder BuilderIO viewModelBuilderInput = new BuilderIO(); //The View Model Builder is a conglomerate of repositories and methods used to Construct a View Model out of Business Objects SampleViewModel viewModel = sampleViewModelBuilder.Build(viewModelBuilderInput); return View("SampleView", viewModel); } [AcceptVerbs(HttpVerbs.Post)] public ActionResult SampleView(SampleViewModel viewModel) { // The array of Guids successfully bound to the SelectedObjectIds property of the View Model! return View(); } 

    Любой, кто знаком с философией View Model, будет радоваться, это работает как Champ!

    Я также хотел бы указать, что вы можете назвать каждый флажок другим именем и иметь это имя в параметрах actionresults.

    Пример,

    Посмотреть:

      < %= Html.CheckBox("Rs232CheckBox", false, new { @id = "rs232" })%>RS-232 < %= Html.CheckBox("Rs422CheckBox", false, new { @id = "rs422" })%>RS-422 

    controller:

     public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) { ... } 

    Значения из представления передаются в действие, так как имена одинаковы.

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

       

    Из controllerа:

      [AcceptVerbs(HttpVerbs.Post)] public ActionResult Index(FormCollection fc) { var s = fc["checkbox1"]; if (s == "on") { string x = "Hi"; } } 

    Эта проблема также возникает и в версии 1.0. Html.Checkbox () вызывает добавление другого скрытого поля с тем же именем / идентификатором, что и в вашем исходном флажке. И когда я пытался загружать блок checkbox с помощью document.GetElemtentsByName (), вы можете догадаться, как все обманывается. Это странно.

    Из того, что я могу собрать, модель не хочет угадывать, была ли check = true или false, я обошел это, установив атрибут value в элементе checkbox с jQuery перед отправкой формы следующим образом:

      $('input[type="checkbox"]').each(function () { $(this).attr('value', $(this).is(':checked')); }); 

    Таким образом, вам не нужен скрытый элемент, чтобы сохранить значение флажка.

    Я знаю, что этот вопрос был написан, когда MVC3 не вышел, но для тех, кто приходит к этому вопросу и использует MVC3, вам может понадобиться «правильный» способ сделать это.

    Хотя я думаю, что выполнение всего

     Contains("true"); 

    вещь велика и чиста, и работает на всех версиях MVC, проблема в том, что она не учитывает культуру (как если бы это действительно имело значение в случае bool).

    «Правильный» способ определить значение bool, по крайней мере в MVC3, – использовать ValueProvider.

     var value = (bool)ValueProvider.GetValue("key").ConvertTo(typeof(bool)); 

    Я делаю это на одном из сайтов моего клиента, когда я редактирую разрешения:

     var allPermissionsBase = Request.Params.AllKeys.Where(x => x.Contains("permission_")).ToList(); var allPermissions = new List>(); foreach (var key in allPermissionsBase) { // Try to parse the key as int int keyAsInt; int.TryParse(key.Replace("permission_", ""), out keyAsInt); // Try to get the value as bool var value = (bool)ValueProvider.GetValue(key).ConvertTo(typeof(bool)); } 

    Теперь красота этого заключается в том, что вы можете использовать это практически с любым простым типом, и это будет даже правильно, основываясь на Культуре (думаю, деньги, десятичные числа и т. Д.).

    ValueProvider – это то, что используется, когда вы формируете свои действия следующим образом:

     public ActionResult UpdatePermissions(bool permission_1, bool permission_2) 

    но когда вы пытаетесь динамически создавать эти списки и проверять значения, вы никогда не узнаете Id во время компиляции, поэтому вам придется обрабатывать их на лету.

    Самый простой способ сделать это так …

    Вы задаете имя и значение.

    @item.Name

    Затем при подаче захватить значения флажков и сохранить в массиве int. затем соответствующую функцию LinQ. Это оно..

     [HttpPost] public ActionResult Checkbox(int[] selectedObjects) { var selected = from x in selectedObjects from y in db where y.ObjectId == x select y; return View(selected); } 

    То же, что и ответ nautic20, просто используйте флажок привязки модели MVC по умолчанию с тем же именем, что и свойство коллекции string / int / enum в ViewModel. Вот и все.

    Но один вопрос нужно указать. В каждом компоненте флажка вы не должны помещать в него «Id», который повлияет на привязку модели MVC.

    Следующий код будет работать для привязки к модели:

      < % foreach (var item in Model.SampleObjectList) { %>   < %= Html.Encode(item.Name)%>  < % } %> 

    Следующие коды не будут привязываться к модели (разница здесь – это идентификатор для каждого флажка)

     < % foreach (var item in Model.SampleObjectList) { %>   < %= Html.Encode(item.Name)%>  < % } %> 

    это то, что я сделал, чтобы потерять двойные значения при использовании Html.CheckBox (…

     Replace("true,false","true").Split(',') 

    с четырьмя отмеченными флажками, непроверенными, непроверенными, проверяется, что это правда, false, false, false, true, false в true, false, false, true. только то, что мне нужно

    Как насчет чего-то подобного?

     bool isChecked = false; if (Boolean.TryParse(Request.Form.GetValues(”chkHuman”)[0], out isChecked) == false) ModelState.AddModelError(”chkHuman”, “Nice try.”); 

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

    Таким образом, выполнение «проверенного» или истинного теста будет следующим:

     //looking for [true],[false] bool isChecked = form.GetValues(key).Contains("true"); 

    Выполнение ложной проверки:

     //looking for [false],[false] or [false] bool isNotChecked = !form.GetValues(key).Contains("true"); 

    Основное различие заключается в использовании GetValues поскольку он возвращается как массив.

    Просто сделайте это на $(document).ready :

     $('input:hidden').each(function(el) { var that = $(this)[0]; if(that.id.length < 1 ) { console.log(that.id); that.parentElement.removeChild(that); } }); 

    Мое решение:

        

    Подробнее вы можете найти здесь: http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-of-string-was-not-recognized-as-a- действительный-логический /

    У меня была почти та же проблема, но возвращаемое значение моего controllerа было заблокировано другими значениями.

    Нашел простое решение, но оно кажется немного грубым.

    Попробуйте ввести Viewbag. в вашем controllerе, и теперь вы даете ему имя, например Viewbag.Checkbool

    Теперь переключитесь на View и попробуйте это @Viewbag.Checkbool с этим вы получите значение из controllerа.

    Параметры моего controllerа выглядят следующим образом:

     public ActionResult Anzeigen(int productid = 90, bool islive = true) 

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

      

    Используя @mmacaulay, я придумал это для bool:

     // MVC Work around for checkboxes. bool active = (Request.Form["active"] == "on"); 

    Если отмечено active = true

    Если unchecked active = false

    Interesting Posts

    Android: получение общих настроек другого приложения

    Должны ли быть написаны модульные тесты для геттеров и сеттеров?

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

    Поделитесь Интернетом через ноутбук Dell Windows 7

    Где хранятся файлы в корзине в отношении разделов?

    Как я получу последний день месяца?

    Автоматическая блокировка экрана для любого пользователя после определенного периода бездействия в Windows 7

    Мои структуры не сортируются в json

    Поместить постоянный текст внутри EditText, который должен быть не редактируемый – Android

    Как исправить ошибку COMException 80040154?

    .htaccess & WordPress: Исключить папку из RewriteRule

    Создание пользовательского расширения файла с реестром Windows

    Место на жестком диске меньше рекламируемого

    Что такое fragmentация памяти?

    Как переключить JPanels внутри JFrame

    Давайте будем гением компьютера.