Отримання значення прапорця в 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());
}

Я не можу це зрозуміти. Чому не встановлено значення прапорця?


Чи надсилається повідомлення з належним значенням? Чи можете ви перевірити це за допомогою fiddler? Крім того, я не знаю, чи / як значення прапорця перекладається на bool.
shahkalpesh

Це надсилається у формі "увімкнено" або "вимкнено". Це, мабуть, не пов'язує правильно. Я зробив дурну перерахунок, щоб уникнути цього.
Ябларго

@Yablargo, вам не потрібні перерахунки. Просто додайте value = "true" у вхідний тег. І використовуйте прихований з value = "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)
  • Якщо встановлено прапорець, то форма подає два поля (хибні та істинні) та набори MVC trueдля boolвластивості моделі

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

Це завжди надсилатиме значення за замовчуванням, якщо воно встановлено.


7
Привіт, ця поведінка призводить до того, що моя модель не може перевірити, оскільки вона, здається, не зможе зрозуміти, як перетворити [справжнє, хибне] в єдине булеве значення. Як ти обіймаєш це?
Оби

@ObiOnuorah Яку конструкцію ви використовуєте? Допомога чи жорстко розмічена HTML-розмітка?
розробник

5
Html.EditorFor або Html.CheckBoxFor або дає однаковий результат
Obi

3
Якщо використовується formCollection, то рядок, який повертається для прапорця, є результатом: "true, false". Як ти розбираєш це? Чи замінити () єдиний варіант?
Jo Smo

7
Якщо ви додаєте власні прапорці вручну, то ключовою частиною є те, що для цього значення слід встановити значення "true" , інакше значення, яке повертається формою за замовчуванням, буде "on", а "on" не може бути прив'язане до bool якому потрібно істинно / хибно. (Можливо, ви побачите помилку перевірки, що значення "on" недійсне для поля .)
Greg

69

Оскільки ви використовуєте Model.Name для встановлення значення. Я припускаю, що ви передаєте порожню модель перегляду до Перегляду.

Таким чином, значення для пам'яті є помилковим і встановлює значення для елемента прапорця на значення 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

Для перетворення значення, поверненого з прапорця у формі, у властивість Boolean, я використовував конвертер збірки ValueProviderResult у власному ModelBinder.

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

3

Якщо працювати з FormCollection, а не модель, призначення може бути таким же простим, як:

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

2

Я зіткнувся з подібною проблемою і зміг повернути значення прапорець за допомогою прапорця, hiddenfor та маленького 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
Привіт Surendran і ласкаво просимо до Stack Overflow. Коли ви включаєте код, будь ласка, відформатуйте його для читання. Але що ще важливіше, важливо пояснити, чому включений код вирішує питання ОП.
Олексій А.

1

Для MVC з використанням моделі. Модель:

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

Для декількох прапорців з тим самим іменем ... Код для видалення непотрібної помилки:

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; }
}

Використовуйте нульовий 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.