Получение значения флажка в ASP.NET MVC 4


122

Я работаю над приложением ASP.NET MVC 4. Это приложение имеет базовую форму. Модель моей формы выглядит следующим образом:

public class MyModel
{
    public string Name { get; set; }
    public bool Remember { get; set; }
}

В моей форме есть следующий HTML-код.

<input id="Name" name="Name" type="text" value="@Model.Name" />
<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />
<label for="Remember">&nbsp;Remember Me?</label>

Когда я публикую форму, значение «Запомнить» в модели всегда ложно. Однако свойство Name в модели имеет значение. Я проверил это, установив точку останова следующим образом:

[HttpPost]
public ActionResult MyAction(MyModel model)
{
  Console.WriteLine(model.Remember.ToString());
}

Я не могу этого понять. Почему не устанавливается значение флажка?


Публикуется ли оно с правильным значением? Можете ли вы проверить это с помощью скрипачей? Кроме того, я не знаю, переводится ли / как значение флажка в bool.
shahkalpesh 06

Это будет опубликовано в форме как «включено» или «отключено». Очевидно, это неправильно. Я сделал глупое перечисление, чтобы этого избежать.
Yablargo

@Yablargo, тебе не нужно перечисление. Просто добавьте value = "true" во входной тег. И используйте скрытый со значением = "false", как показано ниже.
сочувствующий Грег

Ответы:


213
@Html.EditorFor(x => x.Remember)

Сгенерирует:

<input id="Remember" type="checkbox" value="true" name="Remember" />
<input type="hidden" value="false" name="Remember" />

Как это работает:

  • Если checkboxфлажок не установлен, форма отправляет только hiddenзначение (false)
  • Если этот флажок установлен, форма отправляет два поля (false и true) и наборы MVC trueдля boolсвойства модели.

<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

Это всегда будет отправлять значение по умолчанию, если отмечено.


7
Привет, это поведение приводит к тому, что моя модель не проходит валидацию, поскольку она, похоже, не может понять, как превратить [true, false] в одно логическое значение. Как с этим справиться?
Оби

@ObiOnuorah Какую конструкцию вы используете? Помощник ИЛИ жестко запрограммированная разметка html?
webdeveloper

5
Html.EditorFor или Html.CheckBoxFor либо дает тот же результат
Оби

3
Если используется formCollection, то в качестве результата для флажка возвращается строка: «true, false». Как это разобрать? Replace () - единственный вариант?
Jo Smo

7
Если вы добавляете свои собственные флажки вручную, то ключевым моментом является то, что значение должно быть установлено на «true» , в противном случае значение по умолчанию, возвращаемое формой, будет «on», а «on» не может быть привязано к bool. которому нужно истина / ложь. (Вы можете увидеть ошибку проверки, что значение «on» недействительно для поля .)
Грег

69

Поскольку вы используете Model.Name для установки значения. Я предполагаю, что вы передаете в View пустую модель представления.

Таким образом, значение Remember - false, а значение элемента флажка - false. Это означает, что, когда вы затем устанавливаете этот флажок, вы публикуете значение «false» с формой. Если вы не выберете его, он не будет опубликован, поэтому по умолчанию используется значение false. Вот почему в обоих случаях вы видите ложное значение.

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

@Html.CheckBoxFor(x => x.Remember)

или если вы не хотите привязывать модель к виду.

@Html.CheckBox("Remember")

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

Изменить, если у вас действительно есть отвращение к этому и вы хотите создать элемент самостоятельно, вы можете это сделать.

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked=\"checked\"" : "") />

2
@Html.CheckboxForКод должен быть на самом деле@Html.CheckBoxFor
fujiiface

Просто быстрый, как бы вы использовали @(Model.Remember ? "checked=\"checked\"" : "")радио-кнопку? или это невозможно
Иззи

С этой опцией вы просто манипулируя HTML напрямую, радио - кнопка просто type="radio", и выбрать тот , который вы хотите , выбранный в HTML такой же , как и выше, checked="checked". Разница в том, что у вас будет несколько <input />элементов с одинаковым именем. Вам нужно решить, к какому из них применить дополнительный HTML.
Дэн Солтмер

@Html.CheckBoxFor(x => x.Remember)это сработало для меня
JustLearning

15

Используйте только это

$("input[type=checkbox]").change(function () {
    if ($(this).prop("checked")) {
        $(this).val(true);
    } else {
        $(this).val(false);
    }
});

Или:$(this).val($(this).is(":checked"));
Норман

5

Вместо того

 <input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

использовать:

 @Html.EditorFor(x => x.Remember)

Это даст вам флажок специально для "Запомнить"


4

Окей, флажок немного странный. Когда вы используете Html-помощник, он генерирует два ввода флажка в разметке, и оба из них передаются как пара имя-значение IEnumerable, если он установлен.

Если он не отмечен в разметке, он передается только в скрытом вводе со значением false.

Так, например, у вас есть разметка:

      @Html.CheckBox("Chbxs") 

И в действии контроллера (убедитесь, что имя соответствует имени параметра флажка на контроллере):

      public ActionResult Index(string param1, string param2,
      string param3, IEnumerable<bool> Chbxs)

Затем в контроллере вы можете делать что-то вроде:

      if (Chbxs != null && Chbxs.Count() == 2)
        {
            checkBoxOnMarkup = true;
        }
        else
        {
            checkBoxOnMarkup = false;
        }

Я знаю, что это не изящное решение. Надеюсь, кто-то здесь может дать несколько указателей.


3

Чтобы преобразовать значение, возвращаемое флажком в форме, в логическое свойство, я использовал преобразователь сборки ValueProviderResult в настраиваемом ModelBinder.

ValueProviderResult cbValue = bindingContext.ValueProvider.GetValue("CheckBoxName");
bool value = (bool)cbValue.ConvertTo(typeof(bool));

3

Если вы работаете с FormCollection, а не с моделью, назначение может быть таким простым, как:

MyModel.Remember = fields["Remember"] != "false";

2

Я столкнулся с аналогичной проблемой и смог вернуть значение флажка, используя флажок, скрытый для и небольшой JQuery, например:

@Html.CheckBox("isPreferred", Model.IsPreferred)
@Html.HiddenFor(m => m.IsPreferred)

<script>

    $("#isPreferred").change(function () {

        $("#IsPreferred").val($("#isPreferred").val());

    })

</script>

2

Это было большой проблемой, и кажется, что все должно быть проще. Вот моя установка и решение.

Я использую следующий помощник HTML:

@Html.CheckBoxFor(model => model.ActiveFlag)

Затем в контроллере я проверяю сбор и обработку формы соответственно:

bool activeFlag = collection["ActiveFlag"] == "false" ? false : true;
[modelObject].ActiveFlag = activeFlag;

Согласен, я сделал это еще короче, так как user.IsActive = fc["IsActive"] != "false";я все еще чувствую себя грязным из-за сравнения строк.
WildJoe

1

Я только что столкнулся с этим (не могу поверить, что он не включается / выключается!)

В любом случае!

<input type="checkbox" name="checked" />

Разместит значение «включено» или «выключено».

Это НЕ будет связываться с логическим значением, но вы можете сделать это глупое обходное решение!

 public class MyViewModel
 {
     /// <summary>
     /// This is a really dumb hack, because the form post sends "on" / "off"
     /// </summary>                    
     public enum Checkbox
     {
        on = 1,
        off = 0
     }
     public string Name { get; set; }
     public Checkbox Checked { get; set; }
}

1
@Html.EditorFor(x => x.ShowComment)


$(function () {
        // set default value to control on document ready instead of 'on'/'off' 
        $("input[type='checkbox'][name='ShowComment']").val(@Model.ShowComment.ToString().ToLower());
    });

    $("#ShowComment").change(function() {
        // this block sets value to checkbox control for "true" / "false"

        var chkVal = $("input[type='checkbox'][name='ShowComment']").val();
        if (chkVal == 'false') $("input[type='checkbox'][name='ShowComment']").val(true);
        else $("input[type='checkbox'][name='ShowComment']").val(false);

    });

3
Привет Сурендран и добро пожаловать в Stack Overflow. Когда вы включаете код, отформатируйте его для удобства чтения. Но что еще более важно, важно объяснить, почему включенный код отвечает на вопрос OP.
Alex A.

1

Для MVC с использованием Model. Модель:

public class UserInfo
{
    public string UserID { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public bool RememberMe { get; set; }
}

HTML:

<input type="checkbox" value="true" id="checkbox1" name="RememberMe" checked="@Model.RememberMe"/>
<label for="checkbox1"></label>

В функции [HttpPost] мы можем получить ее свойства.

[HttpPost]
public ActionResult Login(UserInfo user)
{
   //...
   return View(user);
}

1

Если вы действительно хотите использовать простой HTML (по какой-либо причине), а не встроенные расширения HtmlHelper, вы можете сделать это таким образом.

Вместо того

<input id="Remember" name="Remember" type="checkbox" value="@Model.Remember" />

попробуйте использовать

<input id="Remember" name="Remember" type="checkbox" value="true" @(Model.Remember ? "checked" : "") />

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

Если вы используете встроенный Html.RenderCheckbox, он фактически выводит два входа: флажок и скрытое поле, так что ложное значение отправляется, когда флажок снят (а не просто ничего). Это может вызвать непредвиденные ситуации, например:


0

Для нескольких флажков с одинаковым именем ... Код для удаления ненужного false:

List<string> d_taxe1 = new List<string>(Request.Form.GetValues("taxe1"));
d_taxe1 = form_checkbox.RemoveExtraFalseFromCheckbox(d_taxe1);

функция

public class form_checkbox
{

    public static List<string> RemoveExtraFalseFromCheckbox(List<string> val)
    {
        List<string> d_taxe1_list = new List<string>(val);

        int y = 0;

        foreach (string cbox in val)
        {

            if (val[y] == "false")
            {
                if (y > 0)
                {
                    if (val[y - 1] == "true")
                    {
                        d_taxe1_list[y] = "remove";
                    }
                }

            }

            y++;
        }

        val = new List<string>(d_taxe1_list);

        foreach (var del in d_taxe1_list)
            if (del == "remove") val.Remove(del);

        return val;

    }      



}

Используй это :

int x = 0;
foreach (var detail in d_prix){
factured.taxe1 = (d_taxe1[x] == "true") ? true : false;
x++;
}

0
public ActionResult Index(string username, string password, string rememberMe)
{
   if (!string.IsNullOrEmpty(username))
   {
      bool remember = bool.Parse(rememberMe);
      //...
   }
   return View();
}

0

Изменить Помните, как это

public class MyModel
{
    public string Name { get; set; }
    public bool? Remember { get; set; }
}

Используйте nullable bool в контроллере и откатитесь к false на null, как это

[HttpPost]
public ActionResult MyAction(MyModel model)
{
    model.Remember = model.Remember ?? false;
    Console.WriteLine(model.Remember.ToString());
}

0

В моем случае я не устанавливал свойство модели «Запомнить» в методе get. Проверьте свою логику в контроллере. Возможно, вы делаете то же самое. Надеюсь, это поможет!


0

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

Моя форма использует Html.EditorFor(e => e.Property)для создания флажка, и, используя FormCollectionв контроллере, он передает строковое значение 'true,false'в контроллер.

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

Поэтому вместо этого я просто проверяю, начинается ли возвращаемая строка со слова, 'true'а затем устанавливаю логическую переменную trueи передаю ее в модель возврата.

if (KeyName.EndsWith("OnOff"))
{
    // set on/off flags value to the model instance
    bool keyTrueFalse = false;
    if(values[KeyName].StartsWith("true"))
    {
        keyTrueFalse = true;
    }
    infoProperty.SetValue(processedInfo, keyTrueFalse);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.