asp.net mvc复选框不一致

时间:2009-06-01 19:12:36

标签: asp.net-mvc checkbox

我在ASP.NET MVC表单上使用了一个复选框,如下所示:

<%=Html.CheckBox("AgreeToRules", Model.AgreeToRules)%>

模型上的AgreeToRules属性是一个布尔值。在测试期间,这一切都很好。但是,现在我们已经开始使用这个应用程序了,我发现以下消息传递中出现了相对较小但很多的错误:

  

System.Web.HttpUnhandledException:   类型异常   'System.Web.HttpUnhandledException'   被扔了。 ---&GT;   System.InvalidOperationException:The   从类型转换参数   键入'System.String'   'System.Boolean'失败了。看到内心   更多信息的例外。 ---&GT;   System.FormatException:Y不是   布尔值的有效值。 ---&GT;   System.FormatException:String不是   被识别为有效的布尔值。

当视图引擎尝试在帖子后呈现表单时,会出现这种情况,并且从ValueProvider返回的复选框的值如下所示:

  

Y,假

OR

  

N,假

以原始形式呈现的html如下所示:

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

在测试期间,我期望(并显示)发布的值看起来像:

  

真,假

如果选中或

  

如果没有检查。那么N和Y来自哪里?

我将用户代理添加到从错误处理程序返回的信息列表中,并且出现(到目前为止)所有错误都发生在带有FF 3.0.10的Windows XP下,但这正是我测试过的和测试期间不存在问题。

有什么想法吗?

4 个答案:

答案 0 :(得分:2)

我正在处理的项目(MVC 2)上遇到了同样的问题。我们用普通的html代码替换了帮助器来解决它:

在: <%= Html.CheckBox("Credit", false, new {@validate = "required"}) %>

后:

<input type="checkbox" name="Credit" value="true" validate="required" />
<input type="hidden" name="Credit" value="false" />

答案 1 :(得分:1)

很可能您的网站受到提交此值的垃圾邮件程序的攻击,而不是真正的用户。我添加自动日志记录和电子邮件的网站越多,这些类型的“探测”和错误就越多(虽然不完全是你提到的类型,复选框的“Y”),我看到它堆积在我的收件箱中。您的日志记录是否还捕获了其余提交的表单内容?

答案 2 :(得分:1)

我找到了问题,并认为我会在这里发布,以防其他人遇到它。某些表单填充程序将使用我使用的名称检测字段,并尝试通过将值设置为用户以前用于类似命名字段的任何内容来自动“填充它们”。从昨晚深夜开始,我还收到“未经许可”和“已订阅”作为名为“OptIn”的复选框的值。

因此,表单填充符将复选框的值更改为某个值,并且用户选中该复选框,从而导致将意外值传输到服务器。

任何有关处理此问题的想法都将受到赞赏。

答案 3 :(得分:1)

今天,我想出了一个类似问题的解决方案,可能会根据您的特殊需求进行调整。它将“按照你的要求”完成工作,但可能不是最可重复使用的解决方案。

您的想法是,您将浏览已发布的表单字段并修复“已损坏”复选框值。您可以创建一个ValueProviderDictionary a.k.a.IDictionary&lt; string,ValueProviderResult&gt;然后将其交给您的UpdateModel方法。

public static IDictionary<string, ValueProviderResult> CreateScrubbedValueProvider(NameValueCollection postedForm, string[] checkboxFieldsToScrub)
{
    Dictionary<string, ValueProviderResult> dict = new Dictionary<string, ValueProviderResult>();
    foreach (string key in postedForm.AllKeys) {
        string[] values = postedForm.GetValues(key);
        if (checkboxFieldsToScrub.Contains(key)) {
            // Ensure we have a "true" value instead of "Y" or "YES" or whatever...
            // Note that with a checkbox, only the first value matters, so we will only
            // worry about values[0] and not values[1] (the "unchecked" value, if exists).
            if (values[0] == "Y" || values[0] == "YES") {
                values[0] = "true";
            }
        }
        string value = String.Join(",", values);
        ValueProviderResult vpr = new ValueProviderResult(values, value, null);
        dict.Add(key, vpr);
    }
    return dict;
}

您的控制器需要在其参数中接受NameValueCollection(或FormCollection),并且您需要将生成的(“擦除的”)值提供程序字典交给UpdateModel方法。我没有完全测试过,但我的版本对我来说非常相似。祝你好运!