Nhận giá trị hộp kiểm trong ASP.NET MVC 4


122

Tôi đang làm việc trên ứng dụng ASP.NET MVC 4. Ứng dụng này có một hình thức cơ bản. Mô hình cho biểu mẫu của tôi trông giống như sau:

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

Trong biểu mẫu của tôi, tôi có HTML sau.

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

Khi tôi đăng biểu mẫu, giá trị Ghi nhớ trong mô hình luôn là sai. Tuy nhiên, thuộc tính Name trong mô hình có một giá trị. Tôi đã kiểm tra điều này bằng cách thiết lập một điểm ngắt như sau:

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

Tôi không thể tìm ra nó. Tại sao giá trị Hộp kiểm không được đặt?


Nó có được đăng với giá trị thích hợp không? Bạn có thể kiểm tra điều đó bằng cách sử dụng fiddler? Ngoài ra, tôi không biết nếu / làm thế nào giá trị của hộp kiểm chuyển thành bool.
shahkalpesh

Điều này được đăng là "bật" hoặc "tắt" vào biểu mẫu. Điều này rõ ràng không ràng buộc đúng. Tôi đã làm một enum ngu ngốc để tránh điều này.
Yablargo

@Yablargo, bạn không cần enum. Chỉ cần thêm giá trị = "true" vào thẻ đầu vào. Và sử dụng một ẩn với value = "false" như hình dưới đây.
greg thần kinh

Câu trả lời:


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

Sẽ tạo ra:

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

Làm thế nào nó hoạt động:

  • Nếu checkboxvẫn không được chọn, biểu mẫu chỉ gửi hiddengiá trị (sai)
  • Nếu được chọn, sau đó hình thức nộp hai lĩnh vực (false và true) và bộ MVC truecho của mô hình boolbất động sản

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

Điều này sẽ luôn gửi giá trị mặc định, nếu được chọn.


7
Xin chào, điều này dễ xảy ra khiến mô hình của tôi không xác thực được vì nó dường như không thể tìm ra cách biến [true, false] thành một giá trị boolean duy nhất. Làm thế nào để bạn giải quyết vấn đề này?
Obi

@ObiOnuorah Bạn đang sử dụng công trình nào? Người trợ giúp HOẶC đánh dấu html được mã hóa cứng?
webdeveloper

5
Html.EditorFor hoặc Html.CheckBoxFor đều cho kết quả giống nhau
Obi

3
Nếu formCollection được sử dụng, thì chuỗi được trả về cho hộp kiểm vì kết quả là: "true, false". Làm thế nào để bạn phân tích cú pháp này? Replace () có phải là lựa chọn duy nhất không?
Jo Smo

7
Nếu bạn đang thêm các hộp kiểm của riêng mình theo cách thủ công, thì phần quan trọng là giá trị đó phải được đặt thành "true" , nếu không giá trị mặc định do biểu mẫu trả về sẽ là "on" và "on" không thể bị ràng buộc thành bool cần đúng / sai. (Bạn có thể thấy lỗi xác thực rằng giá trị "on" không hợp lệ cho trường .)
Greg

69

Vì bạn đang sử dụng Model.Name để đặt giá trị. Tôi giả sử bạn đang chuyển một mô hình dạng xem trống cho Dạng xem.

Vì vậy, giá trị cho Remember là false và đặt giá trị trên phần tử hộp kiểm thành false. Điều này có nghĩa là khi bạn chọn hộp kiểm, bạn đang đăng giá trị "false" với biểu mẫu. Khi bạn không chọn nó, nó sẽ không được đăng, do đó, mô hình mặc định là false. Đó là lý do tại sao bạn thấy giá trị sai trong cả hai trường hợp.

Giá trị chỉ được chuyển khi bạn chọn hộp chọn. Để thực hiện một hộp kiểm trong sử dụng Mvc

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

hoặc nếu bạn không muốn ràng buộc mô hình với dạng xem.

@Html.CheckBox("Remember")

Mvc thực hiện một số phép thuật với một trường ẩn để duy trì các giá trị khi chúng không được chọn.

Chỉnh sửa, nếu bạn thực sự không thích làm điều đó và muốn tự tạo phần tử, bạn có thể làm.

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

2
Các @Html.CheckboxFormã nên thực sự được@Html.CheckBoxFor
fujiiface

Chỉ cần một cái nhìn nhanh, bạn sẽ sử dụng như thế nào @(Model.Remember ? "checked=\"checked\"" : "")trên một nút radio? hoặc là không thể
Izzy

Với tùy chọn đó, bạn chỉ thao tác trực tiếp với HTML, một nút radio type="radio"và việc chọn tùy chọn bạn muốn chọn trong HTML cũng giống như trên , checked="checked". Sự khác biệt là bạn sẽ có nhiều <input />phần tử có cùng tên. Bạn cần tìm ra cái nào trong số đó để áp dụng HTML bổ sung.
Dan Saltmer

@Html.CheckBoxFor(x => x.Remember)này làm việc cho tôi
JustLearning

15

Chỉ sử dụng cái này

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

Hoặc:$(this).val($(this).is(":checked"));
Norman

5

Thay vì

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

sử dụng:

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

Điều đó sẽ cung cấp cho bạn một hộp kiểm dành riêng cho Ghi nhớ


4

Được rồi, hộp kiểm hơi lạ. Khi bạn sử dụng trình trợ giúp Html, nó tạo ra hai đầu vào hộp kiểm trên đánh dấu và cả hai đều được chuyển vào dưới dạng một cặp giá trị tên của IEnumerable nếu nó được chọn.

Nếu nó không được kiểm tra trên đánh dấu, nó chỉ được chuyển vào đầu vào ẩn có giá trị sai.

Vì vậy, ví dụ trên đánh dấu bạn có:

      @Html.CheckBox("Chbxs") 

Và trong hành động của bộ điều khiển (đảm bảo tên khớp với tên tham số hộp kiểm trên bộ điều khiển):

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

Sau đó, trong bộ điều khiển, bạn có thể thực hiện một số thao tác như:

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

Tôi biết đây không phải là một giải pháp thanh lịch. Hy vọng ai đó ở đây có thể cho một số gợi ý.


3

Để chuyển đổi giá trị được trả về từ hộp kiểm trong biểu mẫu thành thuộc tính Boolean, tôi đã sử dụng trình chuyển đổi bản dựng của ValueProviderResult trong ModelBinder tùy chỉnh.

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

3

Nếu làm việc với FormCollection chứ không phải mô hình, việc gán có thể đơn giản như sau:

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

2

Tôi đã gặp sự cố tương tự và có thể lấy lại giá trị hộp kiểm bằng cách sử dụng hộp kiểm, hiddenfor và JQuery nhỏ như vậy:

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

<script>

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

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

    })

</script>

2

Đây là một nỗi đau lớn và cảm thấy nó nên đơn giản hơn. Đây là thiết lập và giải pháp của tôi.

Tôi đang sử dụng trình trợ giúp HTML sau:

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

Sau đó, trong bộ điều khiển, tôi đang kiểm tra việc thu thập và xử lý biểu mẫu cho phù hợp:

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

Đồng ý, tôi đã làm cho điều này ngắn hơn vì user.IsActive = fc["IsActive"] != "false";tôi vẫn cảm thấy bẩn khi thực hiện so sánh chuỗi trên đó.
WildJoe

1

Tôi vừa gặp phải vấn đề này (Tôi không thể tin rằng nó không ràng buộc bật / tắt!)

Dù sao!

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

Sẽ Đăng giá trị "bật" hoặc "tắt".

WONT này liên kết với boolean, nhưng bạn có thể thực hiện cách giải quyết ngớ ngẩn này!

 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
Xin chào Surendran và chào mừng đến với Stack Overflow. Khi bạn bao gồm mã, vui lòng định dạng nó để dễ đọc. Nhưng quan trọng hơn, điều quan trọng là phải giải thích tại sao đoạn mã bao gồm lại giải quyết câu hỏi của OP.
Alex A.

1

Đối với MVC sử dụng Model. Mô hình:

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>

Trong hàm [HttpPost], chúng ta có thể lấy các thuộc tính của nó.

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

1

Nếu bạn thực sự muốn sử dụng HTML thuần túy (vì bất kỳ lý do gì) chứ không phải các tiện ích mở rộng HtmlHelper được tích hợp sẵn, bạn có thể thực hiện theo cách này.

Thay vì

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

thử sử dụng

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

Đầu vào hộp kiểm trong HTML hoạt động để khi chúng được chọn, chúng sẽ gửi giá trị và khi không được chọn, chúng hoàn toàn không gửi bất kỳ thứ gì (điều này sẽ khiến ASP.NET MVC trở về giá trị mặc định của cánh đồng, false ). Ngoài ra, giá trị của hộp kiểm trong HTML có thể là bất kỳ thứ gì không chỉ đúng / sai, vì vậy nếu bạn thực sự muốn, bạn thậm chí có thể sử dụng hộp kiểm cho trường chuỗi trong mô hình của mình.

Nếu bạn sử dụng tích hợp sẵn Html.RenderCheckbox, nó thực sự xuất ra hai đầu vào: hộp kiểm và trường ẩn để một giá trị sai được gửi khi hộp kiểm được bỏ chọn (không chỉ là không có gì). Điều đó có thể gây ra một số tình huống không mong muốn, như sau:


0

Đối với nhiều hộp kiểm có cùng tên ... Mã để loại bỏ sai không cần thiết:

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

Chức năng

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;

    }      



}

Sử dụng nó :

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

Sửa đổi Ghi nhớ như thế này

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

Sử dụng bool nullable trong bộ điều khiển và dự phòng thành false trên null như thế này

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

0

Trong trường hợp của tôi, tôi đã không đặt thuộc tính mô hình "Nhớ" trong phương thức get. Kiểm tra logic của bạn trong bộ điều khiển. Bạn có thể đang làm như vậy. Tôi hy vọng điều này giúp đỡ!


0

Tôi đã đọc qua các câu trả lời khác và không làm cho nó hoạt động - vì vậy đây là giải pháp tôi đã kết thúc.

Biểu mẫu của tôi sử dụng Html.EditorFor(e => e.Property)để tạo hộp kiểm và sử dụng FormCollectiontrong bộ điều khiển, điều này sẽ chuyển một giá trị chuỗi 'true,false'trong bộ điều khiển.

Khi xử lý kết quả, tôi sử dụng một vòng lặp để duyệt qua chúng - tôi cũng sử dụng một InfoPropertythể hiện để đại diện cho giá trị mô hình hiện tại đang được đánh giá từ biểu mẫu.

Vì vậy, thay vào đó, tôi chỉ kiểm tra xem chuỗi được trả về có bắt đầu bằng từ 'true'hay không và sau đó đặt một biến boolean truevà chuyển nó vào mô hình trả về.

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);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.