【问题标题】:How to fix the model to correctly use the MVC Foolproof library?如何修复模型以正确使用 MVC Foolproof 库?
【发布时间】:2015-06-08 12:16:51
【问题描述】:

我正在尝试使用 MVC Foolproof 库来验证我的模型并分别显示错误消息。但是我没有正确应用数据注释,因此验证不起作用。

我的要求是我有两个复选框,并且在提交表单之前至少需要选中其中一个。下面是带有数据注释的模型中两个字段的代码,

    [RequiredIfFalse("CheckBox2", ErrorMessage = "Please select atleast one checkbox.")]
    public bool Checkbox1 { get; set; }

    [RequiredIfFalse("Checkbox1", ErrorMessage = "Please select atleast one checkbox.")]
    public bool CheckBox2 { get; set; }

现在,当我在不选中任何复选框的情况下提交表单时,会提交表单并且不会显示错误。我知道模型和我应用自定义验证属性的方式存在一些逻辑错误,因为如果我将第一个字段设置为 int 或 string 并在选中 CheckBox 时使其成为必需,则验证工作正常,并且验证消息会相应地显示在风景。请帮助我识别上述字段中的逻辑错误。

【问题讨论】:

    标签: asp.net-mvc-5 foolproof-validation


    【解决方案1】:
    [Required]
    public bool DidWin {get;set;}
    
    [RequiredIfFalse(nameof(DidWin))]
    public string ExplainationWhyDidntWin {get;set;}  // Doesn't work
    
    [RequiredIfNot(nameof(DidWin), true)]
    public string ExplainationWhyDidntWin2 {get;set;} // Works
    

    为了解决这个问题,找到mvcfoolproof.unobtrusive.js并替换以下内容:

    var isBool = function (input) {
        return input === true || input === false || input === "true" || input === "false";
    };
    

    var isBool = function (input) {
        return input === true || input === false || input.toLowerCase() === "true" || input.toLowerCase() === "false";
    };
    

    else if (isBool(value1)) {
        if (value1 == "false") value1 = false;
        if (value2 == "false") value2 = false;
        value1 = !!value1;
        value2 = !!value2;
    }
    

    else if (isBool(value1) && isBool(value2)) {
        if (value1 == "false") value1 = false;
        if (value2.toLowerCase() == "false") value2 = false;
        value1 = !!value1;
        value2 = !!value2;
    }
    

    【讨论】:

    • 这是与问题完全不同的场景(这是 2 个类型为 bool 的属性),因此不是问题的答案(并且进行这些更改无助于解决 OP 的问题)
    【解决方案2】:

    一个布尔值只有 2 个状态(truefalse),其中任何一个都是有效的,所以 [RequiredIfFalse] 有效地表示该值必须是 truefalse,它总是会假设你使用@Html.CheckBoxFor()。您不能为此使用万无一失的验证属性。

    【讨论】:

    • 感谢您的回复。必须有某种方法可以使用 Foolproof 来验证这一点。一些解决方法?
    • 不,没有。 “必需”表示其必需(非空),boolean 永远不会为空。最简单的解决方法是检查POST方法中的值,如果两者都是false,则添加模型状态错误-ModelState.AddModelError("", "Please check Checkbox1 and/or Checkbox2");,它将显示在@Html.ValidationSummary()
    • 原谅我,但感觉很奇怪。如果 CheckBox 未选中,则其值为 false,如果已选中,则其值为 true。因此,RequiredIfFalse 应该意味着如果 CheckBox 未选中则显示消息。您所说的是 RequiredIfFalse 不起作用,因为它不为空。我说的是RequiredIfFalse,而不仅仅是必需
    • 你显然不懂逻辑。 [RequiredIfFalse("CheckBox2")] 应用于属性CheckBox1 表示如果CheckBox2 的值为false,则需要CheckBox1 的值。这意味着如果CheckBox2false,那么CheckBox1 必须有一个值——它总是 会有一个值,因为truefalse 都是值! (boolean 不能有 null 值`)
    • 谢谢。我错了,因为我认为RequiredIfFalse 正在检查复选框的错误值,而这显然不是。但显然你也不对,这没有其他解决方案。我玩弄了其他属性,发现 [RequiredIfNot("CheckBox1", true) 满足我的要求。唯一的缺点是,当两个 CheckBox 都没有被选中时,它会为两个 CheckBox 显示错误消息,但是当至少一个 CheckBox 被选中时,则没有错误。如果其他人需要,我会将其作为答案发布,并感谢您向我阐明逻辑。
    【解决方案3】:

    我发现我的问题在我修改 Foolproof 的 Data Annotations 后解决了,

        [RequiredIfNot("CheckBox2", true, ErrorMessage = "Please select atleast one checkbox.")]
        public bool CheckBox1 { get; set; }
    
        [RequiredIfNot("CheckBox1", true, ErrorMessage = "Please select atleast one checkbox.")]
        public bool CheckBox2 { get; set; }
    

    通过这个,我实际上是在检查使用RequiredIfFalse 没有达到的值,该值用于检查是否提供了值,我认为它正在检查字段值是否为假。感谢@Stephen Muecke 向我澄清。

    唯一的缺点是,当两个复选框都未选中时,会为我只想显示一次的两个控件显示错误消息。但是当任何一个复选框被选中时,验证就可以正常工作并且不会显示任何错误消息。

    编辑:如果我对任何 CheckBox 使用 ErrorMessage="",则会删除重复的错误消息。因此,如果没有选中 CheckBox,则会显示一次错误消息,如果选中任何 CheckBox,则不会显示错误消息。

    编辑: 这是查看的代码,

                <div class="col-sm-3">
                    @Html.CheckBoxFor(m => m.CheckBox1)
                    @Html.LabelFor(m => m.CheckBox1)
                </div>
    
                <div class="col-sm-3">
                    @Html.CheckBoxFor(m => m.CheckBox2)
                    @Html.LabelFor(m => m.CheckBox2)
                </div>
    

    模型的代码也给出了,现在我已经提供了代码供查看。控制器上没有做任何其他事情,它无需破解即可工作。错误会自动显示在验证摘要中。我也使用了 ValidationFor,它也可以正常工作。

    【讨论】:

    • 不太确定你声称这是如何工作的(它没有)。 [RequiredIfNot](派生自[RequiredIf] 意味着它所应用的属性必须具有基于另一个属性的值的值(即不是null 或不是空的string)。因为布尔值总是truefalse(不能是null 或空的string)验证总是通过。您可以查看IsValid() 方法here 的源代码
    • 我只能假设您没有使用@Html.CheckBoxFor() 或者您在视图中进行了一些修改以使其工作
    • @Stephen Muecke 我正在使用@Html.CheckBoxFor() 并且没有使用任何其他黑客。
    • @Stephen Muecke 你必须至少尝试一次才能看到它是如何工作的。你之前是对的,但这次不是。您只看到RequiredIfNot,但请查看参数。如果您将看到参数,那么您将知道它正在与值进行比较。我不明白为什么你认为这不起作用,为什么你坚持,但它对我来说绝对没问题。我会坚持尝试摆脱拒绝状态。
    • 我试过了(包括下载源代码和单步调试)。如果我之前是对的,那么我又是对的,因为 [RequiredIfFalse("CheckBox2")][RequiredIfNot("CheckBox2", true] 相同 - 查看源代码 - 第一个只是第二个的捷径(它们都源自 [RequiredIf] - 第一个只是自动生成第二个参数,所以你不需要传递它)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-24
    • 2015-09-25
    相关资源
    最近更新 更多