MVC Html.CheckBox and form submit issue
在ASP.NET MVC RC中的Html.Checkbox中提交值的疯狂问题
有些值只是不传给Request.Params
在我的表格中,我在循环内有这行:
并呈现到下一个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <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" /> |
提交表格后,我得到如下信息:
1 2 3 4 5 | Form.Params["cb17"] = {6,"false"} Form.Params["cb18"] = {6,"false"} Form.Params["cb19"] = {"false"} Form.Params["cb20"] = {"6,false"} Form.Params["cb21"] = {"false"} |
在请求字符串中,某些参数显示两次(正常情况),而某些仅显示一次(仅隐藏字段的值)。
似乎并不依赖于是否已选中复选框,值是否已更改...
有人遇到这种情况吗? 我该如何解决?
1 2 3 4 5 6 7 8 9 10 | <% 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"/> <% } %> |
并在您的控制器中
1 2 3 4 5 6 7 | List=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 } |
您检查错误的原因是因为" Html复选框"帮助程序做了某种怪异的事情,使值成为true
真实回报为:
1 | it makes the string read"true, false" |
所以您可能以为这是两个值,但它只是一个值,表示真实
错误返回为:
1 | it makes the string read"false" |
实际上,这就是它应该按照规范工作的方式。
它与ASP.NET MVC无关,但是如果未选中此复选框,则它不包含在POST集合中。
之所以会得到两个值,是因为您同时具有一个复选框和一个具有相同名称的输入(并且您拥有两个值的输入很可能选中了复选框)。
编辑:W3C的规范
无需在表单提交后/保存之前询问数据库有关ID的信息(无状态模式),我产生了以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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)); } } } |
谢谢你们帮助我解决此问题!
我用这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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"); } } |
然后这样称呼它:
1 2 | EditedCheckboxValue issomething = new EditedCheckboxValue(collection,"FieldName"); instance.IsSomething = issomething.Current; |