MVC不显眼的验证复选框不起作用

Sni*_*fer 23 unobtrusive-javascript razor unobtrusive-validation asp.net-mvc-3

我试图在提到执行代码这篇文章.换句话说,我正试图在条款和条件复选框上实现不显眼的验证.如果用户未选中该复选框,则应将输入标记为无效.

这是服务器端Validator代码,我添加了:

/// <summary>
/// Validation attribute that demands that a boolean value must be true.
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是模型

[MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
[DisplayName("Accept terms and conditions")]
public bool AcceptsTerms { get; set; }
Run Code Online (Sandbox Code Playgroud)

这是我的看法:

@Html.EditorFor(x => x.AcceptTermsAndConditions)
@Html.LabelFor(x => x.AcceptTermsAndConditions)
@Html.ValidationMessageFor(x => x.AcceptTermsAndConditions)
Run Code Online (Sandbox Code Playgroud)

这是我用来附加验证器客户端的jQuery:

$.validator.unobtrusive.adapters.addBool("mustbetrue", "required");
Run Code Online (Sandbox Code Playgroud)

但是,客户端脚本似乎没有被踢入.每当我按下提交按钮时,其他字段的验证就会很好,但条款和条件的验证似乎没有启动.这就是我点击提交按钮后代码在Firebug中的样子.

<input type="checkbox" value="true" name="AcceptTermsAndConditions" id="AcceptTermsAndConditions" data-val-required="The I confirm that I am authorised to join this website and I accept the terms and conditions field is required." data-val="true" class="check-box">
<input type="hidden" value="false" name="AcceptTermsAndConditions">
<label for="AcceptTermsAndConditions">I confirm that I am authorised to join this website and I accept the terms and conditions</label>
<span data-valmsg-replace="true" data-valmsg-for="AcceptTermsAndConditions" class="field-validation-valid"></span>
Run Code Online (Sandbox Code Playgroud)

有任何想法吗?我错过了一步吗?这让我闷闷不乐!

在此先感谢S.

Dar*_*rov 37

您需要在自定义属性上实现IClientValidatable,以便将mustbetrue您在客户端注册的适配器名称与此属性绑定:

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "mustbetrue"
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

完整的工作示例.

模型:

public class MyViewModel
{
    [MustBeTrue(ErrorMessage = "You must accept the terms and conditions")]
    [DisplayName("Accept terms and conditions")]
    public bool AcceptsTerms { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel();
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}
Run Code Online (Sandbox Code Playgroud)

视图:

@model MyViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    $.validator.unobtrusive.adapters.addBool("mustbetrue", "required");
</script>

@using (Html.BeginForm())
{
    @Html.CheckBoxFor(x => x.AcceptsTerms)
    @Html.LabelFor(x => x.AcceptsTerms)
    @Html.ValidationMessageFor(x => x.AcceptsTerms)
    <input type="submit" value="OK" />
}
Run Code Online (Sandbox Code Playgroud)

  • 这里只是一个有用的信息.这行``$ .validator.unobtrusive.adapters.addBool("mustbetrue","required");``必须添加到``<script type ="text/javascript">``就像Dimitrov一样.如果你把它添加到``$(document).ready(function(){``里面就不行了.你不需要在jquery.validate.unobtrusive文件中添加任何内容. (5认同)
  • 效果很好!为了使用本地化的错误消息(使用`ErrorMessageResourceType`和`ErrorMessageResourceName`)而不是客户端上的默认必需消息,我不得不将Attribute定义中的一行更改为`ErrorMessage = FormatErrorMessage(metadata.DisplayName), ` (3认同)

cou*_*ben 26

嗅探器,

除了实现Darin的解决方案之外,您还需要修改该文件jquery.validate.unobtrusive.js.在此文件中,您必须添加"mustbetrue"验证方法,如下所示:

$jQval.addMethod("mustbetrue", function (value, element, param) {
    // check if dependency is met
    if (!this.depend(param, element))
        return "dependency-mismatch";
    return element.checked;
});
Run Code Online (Sandbox Code Playgroud)

然后(我忘了先添加它),你还必须添加以下内容jquery.validate.unobtrusive.js:

adapters.add("mustbetrue", function (options) {
    setValidationValues(options, "mustbetrue", true);
});
Run Code Online (Sandbox Code Playgroud)

counsellorben

  • 我正在使用`$ .validator.addMethod()`和`$ .validator.unobtrusive.adapters.add()`在外部添加自定义验证器. (2认同)

Ada*_*dam 5

我不确定为什么这对我不起作用,但我选择使用你的代码并做一些稍微不同的事情.

在我的JavaScript加载中,我添加了以下内容,如果您选中复选框并取消选中它,则会使复选框触发不显眼的验证.另外,如果您提交表格.

$(function () {
        $(".checkboxonblurenabled").change(function () {
            $('form').validate().element(this);
        });
});
Run Code Online (Sandbox Code Playgroud)

您还需要将CSS类添加到复选框中,如此.

@Html.CheckBoxFor(model => model.AgreeToPrivacyPolicy, new { @class = "checkboxonblurenabled"})
Run Code Online (Sandbox Code Playgroud)

因此,我们现在需要连接模型并输入类来处理服务器端验证(我从上面重新使用),但稍微改变了不引人注目的情况.

这是扩展IClientValidate的customer属性,如上例所示......

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class MustBeTrueAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        return value != null && value is bool && (bool)value;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = this.ErrorMessage,
            ValidationType = "mustbetrue"
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

在模型中,object属性设置所需的属性表示法

 [MustBeTrue(ErrorMessage = "Confirm you have read and agree to our privacy policy")]
    [Display(Name = "Privacy policy")]
    public bool AgreeToPrivacyPolicy { get; set; }
Run Code Online (Sandbox Code Playgroud)

好的,我们准备加入JavaScript了.

(function ($) {
    /*
    START CHECK MUST BE TRUE - UNOBTRUSIVE JAVASCRIPT
    START CHECK MUST BE TRUE - UNOBTRUSIVE JAVASCRIPT
    START CHECK MUST BE TRUE - UNOBTRUSIVE JAVASCRIPT
    */
    jQuery.validator.unobtrusive.adapters.add("mustbetrue", ['maxint'], function (options) {
        options.rules["mustbetrue"] = options.params;
        options.messages["mustbetrue"] = options.message;
    });

    jQuery.validator.addMethod("mustbetrue", function (value, element, params) {

        if ($(element).is(':checked')) {
            return true;
        }
        else {
            return false;
        }
    });
    /*
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    START CHECK MAX INT - UNOBTRUSIVE JAVASCRIPT
    */



} (jQuery));
Run Code Online (Sandbox Code Playgroud)

这项工作的成果是......好吧.在尝试执行上面建议的答案后查看HTML标记后,我的值都设置为true,但是我选中的复选框是false.所以,我决定让jQuery使用IsChecked来解决它