MVC Html.CheckBox 和表单提交问题
Posted
技术标签:
【中文标题】MVC Html.CheckBox 和表单提交问题【英文标题】:MVC Html.CheckBox and form submit issue 【发布时间】: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"
在请求字符串中有些参数显示两次(正常情况),有些只显示一次(只有隐藏字段的值)。 似乎它不依赖于复选框是否被选中,值是否发生了变化......
有人遇到过这种情况吗?我该如何解决?
【问题讨论】:
【参考方案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;
【讨论】:
以上是关于MVC Html.CheckBox 和表单提交问题的主要内容,如果未能解决你的问题,请参考以下文章