客户端非侵入性验证未按预期工作
Client-Side unobtrusive validation not working as expected
我正在为 MVC 应用程序实施自定义不显眼的客户端 JavaScript。当我按下提交按钮时,自定义验证方法([EnforceTrue] 属性)确实会触发,但它没有任何效果。在提交事件中,Form.valid() 方法 return 为真,尽管自定义方法 return 为假值。 (我将其硬编码为 false)。
我在 Whosebug 上阅读了关于不显眼验证的主题,发现无数的设计、选项、想法、建议等都没有帮助。我尝试通过 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。在底部,它捕获提交事件,然后检查表单是否已验证。有效().
@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');
//
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() 方法在未选中复选框时为 return false,并在屏幕上显示错误消息(就像默认的 [Required] 属性所做的那样)。
也许我这边的某个地方疏忽了?
删除
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
第二次包含 jquery 的代码段最终解决了问题。
我正在为 MVC 应用程序实施自定义不显眼的客户端 JavaScript。当我按下提交按钮时,自定义验证方法([EnforceTrue] 属性)确实会触发,但它没有任何效果。在提交事件中,Form.valid() 方法 return 为真,尽管自定义方法 return 为假值。 (我将其硬编码为 false)。
我在 Whosebug 上阅读了关于不显眼验证的主题,发现无数的设计、选项、想法、建议等都没有帮助。我尝试通过 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。在底部,它捕获提交事件,然后检查表单是否已验证。有效().
@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');
//
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() 方法在未选中复选框时为 return false,并在屏幕上显示错误消息(就像默认的 [Required] 属性所做的那样)。
也许我这边的某个地方疏忽了?
删除
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
第二次包含 jquery 的代码段最终解决了问题。