【问题标题】:Handling Checkbox values in MVC 4在 MVC 4 中处理复选框值
【发布时间】:2014-11-13 14:46:06
【问题描述】:

我的 MVC 视图中的表单内有一个复选框,如下所示:

<div class="row" style="width: 98%;">
  <div class="col-md-1" style="width: 22%;">Active</div>
  <div class="col-md-1" style="width: 23%;">
    <input type="checkbox" ID="chb_Active" style="color: #428bca;">
  </div>
  <div class="col-md-1" style="width: 22%;">Inactive</div>
  <div class="col-md-1" style="width: 23%;">
    <input type="checkbox" ID="chb_Inactive" style="color: #428bca;">
  </div>
  <div class="col-md-1" style="width: 20%;"></div>                          
</div>

在我的控制器上,ActionResult 方法如下所示。

public ActionResult MethodName(string submit, FormCollection collection) 
{
  bool chb_Active = Convert.ToBoolean(collection["chb_Active"]);
  bool chb_Inactive = Convert.ToBoolean(collection["chb_Inactive"]);
  //Some other operations
  //The return view
}

这就是我处理所有其他控件(如下拉列表)的方式,这些控件可以正常工作并获取所选值。

问题出现在复选框值上,即使我选中或取消选中它们,它们总是设置为 False,它们总是返回 False。

我是 MVC 新手,请帮助或指出正确的方向。我已经尝试不使用 FormCollection 并且表单仍然没有积极的结果。

大多数与此相关的档案在这种情况下没有帮助,因为它们的复选框中有值。

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-mvc-4


    【解决方案1】:

    这里有两个问题:

    首先,您的 HTML 输入需要一个 name 属性 - 而不仅仅是一个 id - 因为它是用作表单集合中键的名称。

    其次,他们需要一个价值。这更棘手,并且是复选框的一个古老问题。默认情况下,如果选中,浏览器将提交与复选框关联的值,如果未选中,则不会提交任何内容。因此,为了使复选框在选中时提交true,在未选中时提交false,您需要这样做:

    <input type="checkbox" ID="chb_Active" name="chb_Active" value="true" style="color: #428bca;">
    <input type="hidden" name="chb_Active" value="false">
    

    (如果您想要其中两个复选框,则对于您的另一个复选框也是如此)。

    使用此设置,如果未选中复选框,false 将作为表单的 chb_Active 属性的值回发。如果它选中,那么falsetrue 都将被回发,如果你使用它的模型绑定功能,ASP.NET 会自动为你挑选出true,就像这样:

    public ActionResult MethodName(string submit, bool chb_Active) {
        // ...
    }
    

    【讨论】:

    • 谢谢你的工作...抱歉没有及时接受答案。不在办公室。
    【解决方案2】:

    id 属性不支持表单输入,但name 属性支持。

    将输入更改为读取:

    <input type="checkbox" name="chb_Active" ...
    

    将允许将数据发送回控制器。您还应该按照Ben Griffiths' answer 添加value 属性和隐藏输入。


    更好的方法

    更符合 MVC 的方法是使用视图模型。

    创建一个文件夹/ViewModels/ControllerName 并在其中放置一个类(它实际上不必在此文件夹中,但遵循视图后跟的约定很好):

    public class MethodNameViewModel
    {
        public bool Active { get; set; }
        public bool Inactive { get; set; }
    }
    

    鉴于您现在可以这样做

    @model ProjectName.ViewModels.ControllerName.MethodNameViewModel
    
    <div class="row" style="width: 98%;">
        <div class="col-md-1" style="width: 22%;">
            @Html.DisplayNameFor(x => x.Active)
        </div>
        <div class="col-md-1" style="width: 23%;">
            @Html.EditorFor(x => x.Active, new { style = "color: #428bca" })
        </div>
    
        @* Same for other field *@
    

    那么你的post action就变成了:

    [HttpPost]
    public ActionResult MethodName(MethodNameViewModel methodNameViewModel) 
    {
        var active = methodNameViewModel.Active;
        var inactive = methodNameViewModel.Inactive
    
        // ... etc
     }
    

    【讨论】:

    • 我认为您在 A better way to do this 下插入的编辑是一个很好的答案,但在此之前的原始答案具有误导性。简单地在 OP 的原始代码中添加 name 属性并不能解决问题,而且您还没有解释原因
    • @BenGriffiths 啊,刚刚阅读了您的回答,我明白了您的意思。我会在我的答案中添加对您的答案的参考:)
    猜你喜欢
    • 2014-03-22
    • 2013-08-22
    • 2010-12-20
    • 2013-11-23
    • 1970-01-01
    • 2013-11-14
    • 2011-12-15
    • 2021-10-13
    • 2015-10-29
    相关资源
    最近更新 更多