【问题标题】:MVC Html.CheckBox and form submit issueMVC Html.CheckBox 和表单提交问题
【发布时间】:2010-10-14 02:15:44
【问题描述】:

在 ASP.NET MVC RC 的 Html.Checkbox 中提交值的疯狂问题

有些值只是没有出现在 Request.Params

在我的表单中,循环中有这一行:

<%=Html.CheckBox("cb" + p.Option.Id, p.Option.IsAllowed, new { value = 6 })%>

然后渲染到下一个:

    <input checked="checked" id="cb17" name="cb17" type="checkbox" value="6" />
<input name="cb17" type="hidden" value="false" /> 

    <input checked="checked" id="cb18" name="cb18" type="checkbox" value="6" />
<input name="cb18" type="hidden" value="false" /> 

    <input id="cb19" name="cb19" type="checkbox" value="6" />
<input name="cb19" type="hidden" value="false" />

    <input id="cb20" name="cb20" type="checkbox" value="6" />
<input name="cb20" type="hidden" value="false" />

    <input checked="checked" id="cb21" name="cb21" type="checkbox" value="6" />
<input name="cb21" type="hidden" value="false" /> 

提交表单后,我得到如下信息:

Form.Params["cb17"] = {6, "false"}
Form.Params["cb18"] = {6, "false"}
Form.Params["cb19"] = {"false"}
Form.Params["cb20"] = {"6,false"}
Form.Params["cb21"] = {"false"}

在请求字符串中有些参数显示两次(正常情况),有些只显示一次(只有隐藏字段的值)。 似乎它不依赖于复选框是否被选中,值是否发生了变化......

有人遇到过这种情况吗?我该如何解决?

【问题讨论】:

    标签: asp.net-mvc checkbox


    【解决方案1】:

    这实际上是它应该按照规范工作的方式。

    它与 ASP.NET MVC 无关,但是当未选中复选框时,它包含在 POST 集合中。

    你得到两个值,因为你有一个复选框和一个同名的输入(你有两个值的很可能是复选框被选中的那个)。

    编辑:来自 W3C 的 specifications

    【讨论】:

    • 什么?这不是真的 veggerby ...在 mvc 中,复选框的呈现方式与普通的 html 复选框不同
    • 是的,它们被渲染为 2 个输入。但这并不会改变复选框不是 POST 值的一部分这一事实,除非选中这是您查看 Form.Params[] 时得到的结果。如果您将 bool 指定为操作的参数,那么是的,它将按“预期”工作。但这就是 MVC 的“魔力”。
    【解决方案2】:
       <% using(Html.BeginForm("Retrieve", "Home")) %>//Retrieve is the name of the action while Home is the name of the controller
           <% { %>
        <%foreach (var app in newApps)              { %>  
      <tr> 
           <td><%=Html.CheckBox(""+app.ApplicationId )%></td>      
    
       </tr>  
    <%} %>
     <input type"submit"/>
    <% } %>
    

    在你的控制器中

     List<app>=newApps; //Database bind
     for(int i=0; i<app.Count;i++)
     {
    
        var checkbox=Request.Form[""+app[i].ApplicationId];
        if(checkbox!="false")// if not false then true,false is returned
     }
    

    您检查 false 的原因是因为 Html Checkbox 助手为 value true 做了一些奇怪的事情

    True 返回为:

    it makes the string read "true, false"
    

    所以你可能认为它是两个值,但它只是一个并且意味着真实

    False 返回为:

    it makes the string read "false"
    

    【讨论】:

    • 您的解决方案非常好。但我正在考虑提交无状态表单。关于您的示例,我不知道我在 app[i] 中有多少对象
    • 我刚刚更新了。 app[i] 正在遍历页面上的表单 id。由于复选框是动态绑定的,因此您必须在 DB 中找到 id,然后比较表单中的每个值
    • 是否有适当的解释说明为什么会这样?为什么“真假”为真?
    • @chakrit- 从来没有找到任何关于它的文档,只是亲身体验过。我不知道为什么 html 复选框助手的实现会呈现额外的奇怪行为,希望它会在未来的 MVC 版本中得到修复,但我认为它是为了在幕后做一些事情
    • 在您有一个带有复选框和多个页面的网格的情况下,它确实可以更轻松地确定哪些页面已从真变为假。这与您可能将复选框与操作参数关联的事实相结合,这是我能想到此实现的两个原因。
    【解决方案3】:

    在提交表单之后/保存之前(无状态模式)无需向数据库询问 id,我已经生成了这样的代码:

        foreach (string key in Request.Form)
        {
            var checkbox = String.Empty;
            if (key.StartsWith("cb"))
            {
              checkbox = Request.Form["" + key];
    
              if (checkbox != "false")
              {
                  int id = Convert.ToInt32(key.Remove(0, 2));
              }
            }
        }
    

    感谢你们帮助我解决这个问题!

    【讨论】:

      【解决方案4】:

      我用这个:

      public struct EditedCheckboxValue
      {
          public bool Current { get; private set; }
      
          public bool Previous { get; private set; }
      
          public bool Changed { get; private set; }
      
          public EditedCheckboxValue(System.Web.Mvc.FormCollection collection, string checkboxID) : this()
          {
              string[] values = collection[checkboxID].Split(new char[] { ',' });
              if (values.Length == 2)
              {   // checkbox value changed, Format: current,old
                  Current = bool.Parse(values[0]);
                  Previous = bool.Parse(values[1]);
                  Changed = (Current != Previous);
              }
              else if (values.Length == 1)
              {
                  Current = bool.Parse(values[0]);
                  Previous = Current;
                  Changed = false;
              }
              else
                  throw new FormatException("invalid format for edited checkbox value in FormCollection");
          }
      }
      

      然后这样称呼它:

      EditedCheckboxValue issomething = new EditedCheckboxValue(collection, "FieldName");
      instance.IsSomething = issomething.Current;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多