如何为 Asp.NET Core 3.0 的自定义 RequiredIf 属性设置客户端验证
How to set up Client side validation for a custom RequiredIf attribute for Asp.NET Core 3.0
根据各种来源设置验证后,我无法启动我的客户端验证方法。经过大量努力后,我发现更改脚本加载的顺序可以解决问题。我已经提供了一个答案来显示 'RequiredIf' 自定义属性的完整设置 asp.net 核心 3.0 MVC。希望它能为其他人节省宝贵的时间。
创建一个新的 class 继承 ValidationAttribute 和 IClientModelValidator:
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
private string PropertyName { get; set; }
private object DesiredValue { get; set; }
public RequiredIfAttribute(string propertyName, object desiredvalue)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
object instance = context.ObjectInstance;
Type type = instance.GetType();
object propertyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if ((value == null && propertyvalue == DesiredValue) || (value == null && propertyvalue != null && propertyvalue.Equals(DesiredValue)))
{
return new ValidationResult(ErrorMessage);
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-requiredif", errorMessage);
MergeAttribute(context.Attributes, "data-val-requiredif-otherproperty", PropertyName);
MergeAttribute(context.Attributes, "data-val-requiredif-otherpropertyvalue", DesiredValue == null? "": DesiredValue.ToString());
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
}
}
将模型中的属性应用为 属性:
上方的注释
[Display(Name = "Effective Date Column Name")]
[RequiredIf("EffectiveDate", null, ErrorMessage = "Effective Date Column Name is required or Enter an Effective Date.")]
public string ColumnNameEffectiveDate { get; set; }
[Display(Name = "Enter Effective Date")]
public DateTime? EffectiveDate { get; set; }
将验证元素添加到您的 html:
<fieldset>
<legend class="w-auto">Step 4: Set Effective Date</legend>
<div class="form-row">
<div class="form-group col-12">
<small class="form-text">Select the name of the date column to import, or enter a date.</small>
</div>
<div class="form-group col-12 col-lg-4 columnheader">
<label asp-for="@Model.ColumnNameEffectiveDate" class="slightlyBold"></label>
<select class="form-control selectpicker"
asp-for="@Model.ColumnNameEffectiveDate">
<option value="">Nothing selected</option>
</select>
<span asp-validation-for="@Model.ColumnNameEffectiveDate" class="text-danger"></span> <==== HERE
</div>
<div class="form-group col-12 col-lg-2 text-center">
<label class="slightlyBold pt-4">OR</label>
</div>
<div class="form-group col-12 col-lg-4">
<label asp-for="@Model.EffectiveDate" class="slightlyBold">Enter Effective Date:</label>
<input type="text" class="datepicker form-control" asp-for="@Model.EffectiveDate">
</div>
</div>
</fieldset>
在 运行 时,HTML 将更改为包含验证标签:
<select class="form-control selectpicker" data-val="true" data-val-requiredif="Effective Date Column Name is required or Enter an Effective Date." data-val-requiredif-otherproperty="EffectiveDate" data-val-requiredif-otherpropertyvalue="" id="ColumnNameEffectiveDate" name="ColumnNameEffectiveDate" disabled="disabled">
<option value="">Nothing selected</option>
</select>
制作一个 javascript 文件,将新规则添加到不显眼的适配器(我将我的文件命名为“customValidationRules.js”):
$(function () {
jQuery.validator.unobtrusive.adapters.add("requiredif", ["otherproperty", "otherpropertyvalue"],
function (options) {
options.rules["requiredif"] = options.params;
options.messages["requiredif"] = options.message
});
}(jQuery));
和该规则的 运行 方法的第二个文件(我将我的文件命名为“customValidationMethods.js”):
(function ($) {
jQuery.validator.addMethod("requiredif",
function (value, element, parameters) {
var targetId = parameters.otherproperty;
var targetValue = parameters.otherpropertyvalue;
var otherpropertyvalue = (targetValue == null || targetValue == undefined ? "" : targetValue).toString();
var otherpropertyElement = $('#' + targetId);
if (!value.trim() && otherpropertyElement.val() == otherpropertyvalue) {
var isValid = $.validator.methods.required.call(this, value, element, parameters);
return isValid;
}
return true;
}
);
})(jQuery);
确保引用页面所需的验证脚本。脚本的顺序使我的客户端验证开始为自定义属性触发:
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.js"></script>
@*These 4 validation scripts must not be changed*@
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script> <==== HERE
<script src="~/js/customValidationMethods.js"></script> <==== HERE
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script> <==== HERE
<script src="~/js/customValidationRules.js"></script> <==== HERE
@*These 4 validation scripts must not be changed*@
<script src="~/lib/popper.js/umd/popper.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>
根据各种来源设置验证后,我无法启动我的客户端验证方法。经过大量努力后,我发现更改脚本加载的顺序可以解决问题。我已经提供了一个答案来显示 'RequiredIf' 自定义属性的完整设置 asp.net 核心 3.0 MVC。希望它能为其他人节省宝贵的时间。
创建一个新的 class 继承 ValidationAttribute 和 IClientModelValidator:
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
private string PropertyName { get; set; }
private object DesiredValue { get; set; }
public RequiredIfAttribute(string propertyName, object desiredvalue)
{
PropertyName = propertyName;
DesiredValue = desiredvalue;
}
protected override ValidationResult IsValid(object value, ValidationContext context)
{
object instance = context.ObjectInstance;
Type type = instance.GetType();
object propertyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if ((value == null && propertyvalue == DesiredValue) || (value == null && propertyvalue != null && propertyvalue.Equals(DesiredValue)))
{
return new ValidationResult(ErrorMessage);
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
MergeAttribute(context.Attributes, "data-val", "true");
var errorMessage = FormatErrorMessage(context.ModelMetadata.GetDisplayName());
MergeAttribute(context.Attributes, "data-val-requiredif", errorMessage);
MergeAttribute(context.Attributes, "data-val-requiredif-otherproperty", PropertyName);
MergeAttribute(context.Attributes, "data-val-requiredif-otherpropertyvalue", DesiredValue == null? "": DesiredValue.ToString());
}
private bool MergeAttribute(IDictionary<string, string> attributes, string key, string value)
{
if (attributes.ContainsKey(key))
{
return false;
}
attributes.Add(key, value);
return true;
}
}
}
将模型中的属性应用为 属性:
上方的注释[Display(Name = "Effective Date Column Name")]
[RequiredIf("EffectiveDate", null, ErrorMessage = "Effective Date Column Name is required or Enter an Effective Date.")]
public string ColumnNameEffectiveDate { get; set; }
[Display(Name = "Enter Effective Date")]
public DateTime? EffectiveDate { get; set; }
将验证元素添加到您的 html:
<fieldset>
<legend class="w-auto">Step 4: Set Effective Date</legend>
<div class="form-row">
<div class="form-group col-12">
<small class="form-text">Select the name of the date column to import, or enter a date.</small>
</div>
<div class="form-group col-12 col-lg-4 columnheader">
<label asp-for="@Model.ColumnNameEffectiveDate" class="slightlyBold"></label>
<select class="form-control selectpicker"
asp-for="@Model.ColumnNameEffectiveDate">
<option value="">Nothing selected</option>
</select>
<span asp-validation-for="@Model.ColumnNameEffectiveDate" class="text-danger"></span> <==== HERE
</div>
<div class="form-group col-12 col-lg-2 text-center">
<label class="slightlyBold pt-4">OR</label>
</div>
<div class="form-group col-12 col-lg-4">
<label asp-for="@Model.EffectiveDate" class="slightlyBold">Enter Effective Date:</label>
<input type="text" class="datepicker form-control" asp-for="@Model.EffectiveDate">
</div>
</div>
</fieldset>
在 运行 时,HTML 将更改为包含验证标签:
<select class="form-control selectpicker" data-val="true" data-val-requiredif="Effective Date Column Name is required or Enter an Effective Date." data-val-requiredif-otherproperty="EffectiveDate" data-val-requiredif-otherpropertyvalue="" id="ColumnNameEffectiveDate" name="ColumnNameEffectiveDate" disabled="disabled">
<option value="">Nothing selected</option>
</select>
制作一个 javascript 文件,将新规则添加到不显眼的适配器(我将我的文件命名为“customValidationRules.js”):
$(function () {
jQuery.validator.unobtrusive.adapters.add("requiredif", ["otherproperty", "otherpropertyvalue"],
function (options) {
options.rules["requiredif"] = options.params;
options.messages["requiredif"] = options.message
});
}(jQuery));
和该规则的 运行 方法的第二个文件(我将我的文件命名为“customValidationMethods.js”):
(function ($) {
jQuery.validator.addMethod("requiredif",
function (value, element, parameters) {
var targetId = parameters.otherproperty;
var targetValue = parameters.otherpropertyvalue;
var otherpropertyvalue = (targetValue == null || targetValue == undefined ? "" : targetValue).toString();
var otherpropertyElement = $('#' + targetId);
if (!value.trim() && otherpropertyElement.val() == otherpropertyvalue) {
var isValid = $.validator.methods.required.call(this, value, element, parameters);
return isValid;
}
return true;
}
);
})(jQuery);
确保引用页面所需的验证脚本。脚本的顺序使我的客户端验证开始为自定义属性触发:
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.js"></script>
@*These 4 validation scripts must not be changed*@
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script> <==== HERE
<script src="~/js/customValidationMethods.js"></script> <==== HERE
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script> <==== HERE
<script src="~/js/customValidationRules.js"></script> <==== HERE
@*These 4 validation scripts must not be changed*@
<script src="~/lib/popper.js/umd/popper.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.js"></script>