客户端非干扰性验证未按预期工作

Client-Side unobtrusive validation not working as expected

提问人:Stefan 提问时间:9/13/2019 更新时间:9/13/2019 访问量:1793

问:

我正在为 MVC 应用程序实现自定义非侵入式客户端 JavaScript。当我按下提交按钮时,自定义验证方法([EnforceTrue] 属性)确实会触发,但它没有任何效果。在 submit 事件中,Form.valid() 方法返回 true,尽管自定义方法返回 false 值。(我将其硬编码为 false)。

我已经阅读了 Stackoverflow 上关于不显眼验证主题的文章,发现了无数的设计、选项、想法、建议等,但这些设计、选项、想法、建议等并没有完全帮助。我尝试通过 nuget 包引用代码库。我将代码移到了视图的顶部,而不是放在底部。我尝试了更复杂的验证逻辑,但它的行为仍然相同。最终,我将我的应用程序缩小到几行代码,以重现该行为。

这是我的模型:它包含一个必填的名称字段和一个需要在提交之前选中的复选框。该复选框需要自定义验证。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Reflection; // AtLeastOneProperty
using System.Web.Mvc; // Client side Validation STuff (26/08/19)

namespace WebApplication7_POC.Models
{
    public class Consultant
    {

        [Required, Display(Name = "First name:"), MaxLength(80)]
        public string FIRSTNAME { get; set; } // FIRSTNAME

        [Display(Name = "I give my concent.")]
        [EnforceTrue]  // TEST 123
        public bool Concent { get; set; } // AccessAdditional

    }


    public class EnforceTrueAttribute : ValidationAttribute, IClientValidatable
    {
        public override bool IsValid(object value)
        {
            if (value == null) return false;
            if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties.");
            return (bool)value == true;
        }

        public override string FormatErrorMessage(string name)
        {
            return "The '" + name + "' field must be checked in order to continue.";
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            yield return new ModelClientValidationRule
            {
                ErrorMessage = String.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage,
                ValidationType = "enforcetrue"
            };
        }
    }
}

下面是视图。它在顶部实现用于自定义验证的 JQuery。在 botom 上,它捕获 submit 事件,然后检查表单是否已验证。有效()。

@model WebApplication7_POC.Models.Consultant

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<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">

    (function ($) {

        // TEST 123

        $.validator.addMethod("enforcetrue", function (value, element, param) {

            alert('client validation trigerred!');
            console.log(element);
            console.log(element.checked);

            return false;  // element.checked;
        });

        $.validator.unobtrusive.adapters.addBool("enforcetrue");


    }(jQuery));

</script>



@{
    ViewBag.Title = "Consultant";
}

<h2>Consultant</h2>


@using (Html.BeginForm("Consultant","Home",FormMethod.Post,new { id = "HelloForm" }))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Consultant</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.FIRSTNAME, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.FIRSTNAME, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.FIRSTNAME, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Concent, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div class="checkbox">
                    @Html.EditorFor(model => model.Concent)
                    @Html.ValidationMessageFor(model => model.Concent, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Submit it!" class="btn btn-default" />
            </div>
        </div>

    </div>
}



@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}


<script type="text/javascript">


    $(document).ready(function () {

        $("#HelloForm").submit(function () {

            alert('HelloForm submit trigerred');

            // https://stackoverflow.com/questions/53934575/asp-net-core-unobtrusive-client-side-validation-form-onsubmit-fires-even-on-vali

            if ($("#HelloForm").valid()) {
                // Show the Spinner

                alert('Valid!');


                // Sure this works, but it does not validate the custon validation rules.


                // $("#LoaderSpinner").show('hidden');
                // $(".overlay").show();

            } else {

                alert('Not Valid');

            }

        });


    });

</script>

有一个控制器可以处理回发,但我的问题是进行客户端验证。

当按下提交按钮时,我希望 valid() 方法在取消选中复选框时返回 false,并在屏幕上显示错误消息(就像默认的 [Required] 属性一样)。

也许只是在我这边的某个地方疏忽了?

asp.net-mvc 客户端 unobtrusive-validation 自定义属性

评论


答:

1赞 Stefan 9/13/2019 #1

删除

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

第二次包含jQuery的片段最终解决了该问题。