Mendapatkan Nilai Kotak centang di ASP.NET MVC 4


122

Saya sedang mengerjakan aplikasi ASP.NET MVC 4. Aplikasi ini memiliki bentuk dasar. Model formulir saya terlihat seperti berikut:

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

Dalam formulir saya, saya memiliki HTML berikut.

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

Saat saya memposting formulir, nilai Remember dalam model selalu salah. Namun, properti Name dalam model memiliki nilai. Saya telah menguji ini dengan menetapkan breakpoint sebagai berikut:

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

Saya tidak bisa memahaminya. Mengapa nilai Kotak Centang tidak disetel?


Apakah itu diposting dengan nilai yang sesuai? Bisakah Anda memeriksanya menggunakan fiddler? Juga, saya tidak tahu apakah / bagaimana nilai kotak centang diterjemahkan menjadi bool.
shahkalpesh

Ini akan diposting sebagai "aktif" atau "nonaktif" ke formulir. Ini tampaknya tidak mengikat dengan benar. Saya membuat enum bodoh untuk menghindari ini.
Yablargo

@Yablargo, Anda tidak perlu enum. Cukup tambahkan nilai = "true" ke tag masukan. Dan gunakan hidden dengan value = "false" seperti yang ditunjukkan di bawah ini.
Pertemuan simpatrik

Jawaban:


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

Akan menghasilkan:

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

Bagaimana cara kerjanya:

  • Jika checkboxtetap tidak dicentang, formulir hanya mengirimkan hiddennilai (salah)
  • Jika dicentang, maka formulir mengirimkan dua bidang (salah dan benar) dan set MVC trueuntuk boolproperti model

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

Ini akan selalu mengirimkan nilai default, jika dicentang.


7
Hai, behavious ini menyebabkan model saya gagal validasi karena tampaknya tidak dapat mengetahui cara mengubah [true, false] menjadi nilai boolean tunggal. Bagaimana Anda menyiasatinya?
Obi

@ObiOnuorah Konstruksi apa yang Anda gunakan? Helper ATAU markup html hard-code?
pengembang web

5
Html.EditorFor atau Html.CheckBoxFor memberikan hasil yang sama
Obi

3
Jika formCollection digunakan, maka string dikembalikan ke kotak centang sebagai hasilnya adalah: "true, false". Bagaimana Anda mengurai ini? Apakah Replace () satu-satunya pilihan?
Jo Smo

7
Jika Anda menambahkan kotak centang Anda sendiri secara manual, bagian kuncinya adalah nilai tersebut harus disetel ke "true" , jika tidak, nilai default yang dikembalikan oleh formulir akan menjadi "on" dan "on" tidak dapat terikat ke bool yang membutuhkan benar / salah. (Anda mungkin melihat kesalahan validasi bahwa nilai "on" tidak valid untuk bidang .)
Greg

69

Karena Anda menggunakan Model.Name untuk mengatur nilainya. Saya berasumsi Anda melewati model tampilan kosong ke View.

Jadi nilai Remember adalah false, dan menyetel nilai pada elemen kotak centang menjadi false. Artinya ketika Anda kemudian memilih kotak centang, Anda memposting nilai "false" dengan formulir. Jika Anda tidak memilihnya, itu tidak akan diposting, jadi model defaultnya adalah false. Itulah mengapa Anda melihat nilai palsu dalam kedua kasus tersebut.

Nilai hanya diteruskan ketika Anda mencentang kotak pilih. Untuk melakukan kotak centang dalam penggunaan Mvc

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

atau jika Anda tidak ingin mengikat model ke tampilan.

@Html.CheckBox("Remember")

Mvc melakukan sihir dengan bidang tersembunyi untuk mempertahankan nilai saat tidak dipilih.

Sunting, jika Anda benar-benar enggan melakukan itu dan ingin membuat elemen sendiri, Anda bisa melakukannya.

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

2
The @Html.CheckboxForkode harus benar-benar menjadi@Html.CheckBoxFor
fujiiface

Sebentar saja bagaimana Anda menggunakan @(Model.Remember ? "checked=\"checked\"" : "")tombol radio? atau apakah itu tidak mungkin
Izzy

Dengan opsi itu Anda hanya memanipulasi HTML secara langsung, tombol radio cukup type="radio", dan memilih yang ingin Anda pilih di HTML sama seperti di atas , checked="checked". Perbedaannya adalah Anda akan memiliki banyak <input />elemen dengan nama yang sama. Anda perlu mencari tahu yang mana yang akan menerapkan HTML tambahan.
Dan Saltmer

@Html.CheckBoxFor(x => x.Remember)ini berhasil untuk saya
JustLearning

15

Gunakan hanya ini

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

Atau:$(this).val($(this).is(":checked"));
Norman

5

Dari pada

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

menggunakan:

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

Itu akan memberi Anda kotak centang khusus untuk Ingat


4

Oke, kotak centangnya agak aneh. Saat Anda menggunakan helper Html, ini menghasilkan dua input kotak centang pada markup, dan keduanya akan diteruskan sebagai pasangan nama-nilai IEnumerable jika dicentang.

Jika tidak dicentang pada markup, itu akan diteruskan hanya dalam input tersembunyi yang memiliki nilai false.

Jadi misalnya pada markup yang Anda miliki:

      @Html.CheckBox("Chbxs") 

Dan dalam tindakan pengontrol (pastikan namanya cocok dengan nama parameter kotak centang pada pengontrol):

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

Kemudian di pengontrol Anda dapat melakukan beberapa hal seperti:

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

Saya tahu ini bukanlah solusi yang elegan. Semoga seseorang di sini bisa memberikan beberapa petunjuk.


3

Untuk mengonversi nilai yang dikembalikan dari kotak centang dalam formulir menjadi properti Boolean, saya menggunakan konverter ValueProviderResult dalam build di ModelBinder kustom.

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

3

Jika bekerja dengan FormCollection daripada model, tugasnya bisa sesederhana:

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

2

Saya mengalami masalah serupa dan bisa mendapatkan kembali nilai kotak centang dengan menggunakan kotak centang, hiddenfor, dan JQuery kecil seperti:

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

<script>

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

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

    })

</script>

2

Ini telah menjadi rasa sakit yang besar dan terasa seperti itu harus lebih sederhana. Inilah pengaturan dan solusi saya.

Saya menggunakan pembantu HTML berikut:

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

Kemudian, di pengontrol, saya memeriksa pengumpulan dan pemrosesan formulir yang sesuai:

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

Setuju, saya membuat ini lebih pendek karena user.IsActive = fc["IsActive"] != "false";saya masih merasa kotor karena melakukan perbandingan string di atasnya.
WildJoe

1

Saya baru saja mengalami ini (saya tidak percaya itu tidak mengikat / mati!)

Pokoknya!

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

Akan memposting nilai "on" atau "off".

Ini TIDAK AKAN mengikat ke boolean, tetapi Anda dapat melakukan solusi konyol ini!

 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
Halo Surendran dan selamat datang di Stack Overflow. Jika Anda menyertakan kode, harap format agar mudah dibaca. Namun yang lebih penting, penting untuk menjelaskan mengapa kode yang disertakan menjawab pertanyaan OP.
Alex A.

1

Untuk MVC menggunakan Model. 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>

Dalam fungsi [HttpPost], kita bisa mendapatkan propertinya.

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

1

Jika Anda benar-benar ingin menggunakan HTML biasa (untuk alasan apa pun) dan bukan ekstensi HtmlHelper bawaan, Anda dapat melakukannya dengan cara ini.

Dari pada

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

coba gunakan

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

Input kotak centang dalam HTML berfungsi sehingga ketika dicentang, mereka mengirim nilai, dan ketika tidak dicentang, mereka tidak mengirim apa pun sama sekali (yang akan menyebabkan ASP.NET MVC mundur ke nilai default dari lapangan, false). Selain itu, nilai kotak centang di HTML dapat berupa apa saja, tidak hanya benar / salah, jadi jika Anda benar-benar menginginkannya, Anda bahkan dapat menggunakan kotak centang untuk bidang string dalam model Anda.

Jika Anda menggunakan built-in Html.RenderCheckbox, itu sebenarnya mengeluarkan dua input: kotak centang dan bidang tersembunyi sehingga nilai palsu dikirim ketika kotak centang tidak dicentang (bukan hanya tidak ada). Itu dapat menyebabkan beberapa situasi yang tidak terduga, seperti ini:


0

Untuk beberapa kotak centang dengan nama yang sama ... Kode untuk menghapus salah yang tidak perlu:

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

Fungsi

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;

    }      



}

Gunakan :

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

Ubah Ingat seperti ini

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

Gunakan nullable bool di controller dan fallback ke false di null seperti ini

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

0

Dalam kasus saya, saya tidak menyetel properti model "Ingat" dalam metode get. Periksa logika Anda di pengontrol. Anda mungkin melakukan hal yang sama. Saya harap bantuan ini!


0

Saya membaca jawaban lain dan tidak cukup berhasil - jadi inilah solusi yang saya dapatkan.

Formulir saya menggunakan Html.EditorFor(e => e.Property)untuk menghasilkan kotak centang, dan menggunakan FormCollectiondi pengontrol, ini melewati nilai string'true,false' di pengontrol.

Ketika saya menangani hasil, saya menggunakan loop untuk menggilirnya - saya juga menggunakan InfoProperty instance untuk mewakili nilai model saat ini yang dinilai dari formulir.

Jadi sebagai gantinya saya hanya memeriksa apakah string yang dikembalikan dimulai dengan kata 'true'dan kemudian menetapkan variabel boolean ke truedan meneruskannya ke model pengembalian.

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);
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.