ASP.NET MVC Core 3.1 中的条件客户端验证
Conditional client side validation in ASP.NET MVC Core 3.1
我想在 ASP.NET MVC Core 3.1 中进行条件验证。我已经编写了自定义验证,它在服务器端验证中运行良好,但我无法执行客户端验证。在我的示例应用程序中,有一个 Salary 文本框,只有在 Roles 下拉列表中选择 Role=Teacher 时才需要它。能否请您在客户端验证部分帮助我,这是完整的示例代码。
员工模型class
public class Employee
{
public int Id { get; set; }
[Required(ErrorMessage = "Please enter name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter email")]
[EmailAddress]
public string Email { get; set; }
[Required(ErrorMessage = "Please enter role")]
[EnumDataType(typeof(Roles))]
public Roles? Role { get; set; }
[Required(ErrorMessage = "Please Enter Hire Date")]
[Display(Name = "Hire Date")]
public DateTime? HireDate { get; set; }
[RequiredIf("Role", Roles.Teacher, ErrorMessage = "Please enter salary")]
public int? Salary { get; set; }
}
角色枚举
public enum Roles
{
Student = 1,
Teacher = 2,
Assistant = 3
}
RequiredIfAttribute 自定义验证class
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
public string PropertyName { get; set; }
public object Value { get; set; }
public RequiredIfAttribute(string propertyName, object value, string errorMessage = "")
{
PropertyName = propertyName;
ErrorMessage = errorMessage;
Value = value;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var instance = validationContext.ObjectInstance;
var type = instance.GetType();
var proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if (proprtyvalue != null)
{
if (proprtyvalue.ToString() == Value.ToString() && value == null)
{
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
context.Attributes.Add("data-val", "true");
context.Attributes.Add("data-val-country", ErrorMessage);
}
}
UI
的索引视图
@model ASPNETCoreValidations.Models.Employee
@using ASPNETCoreValidations.Models.enums
@{
ViewBag.Title = "Index";
}
<h1>Create</h1>
<h4>Business unit</h4>
<hr />
<div class="container">
<form asp-action="Index">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="col-md-6">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Role" class="control-label"></label>
<select asp-for="Role" class="form-control" asp-items="Html.GetEnumSelectList<Roles>()">
<option value="">Select Department</option>
</select>
<span asp-validation-for="Role" class="text-danger"></span>
</div>
<div class="col-md-6">
<label asp-for="HireDate" class="control-label"></label>
<input asp-for="HireDate" class="form-control" />
<span asp-validation-for="HireDate" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Salary" class="control-label"></label>
<input asp-for="Salary" class="form-control" />
<span asp-validation-for="Salary" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/js/RequiredIfValidate.js"></script>
}
Jquery 用于客户端验证
jQuery.validator.addMethod("requiredif",
function (value, element, param) {
// I need help here. This method never gets executed and I don't know how to implement validation here ...
// return true or false depending on the condition
});
jQuery.validator.unobtrusive.adapters.addBool("requiredif");
索引操作
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(Employee employee)
{
if (ModelState.IsValid)
{
RedirectToAction("Index");
}
return View();
}
根据您的描述,我建议您可以在 RequiredIfAttribute AddValidation 属性中添加一个 属性 以将角色添加到输入工资中。
那么我建议您可以尝试使用以下验证不显眼的脚本:
RequiredIfAttribute :
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
public string PropertyName { get; set; }
public object Value { get; set; }
public RequiredIfAttribute(string propertyName, object value, string errorMessage = "")
{
PropertyName = propertyName;
ErrorMessage = errorMessage;
Value = value;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var instance = validationContext.ObjectInstance;
var type = instance.GetType();
var proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if (proprtyvalue != null)
{
if (proprtyvalue.ToString() == Value.ToString() && value == null)
{
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
context.Attributes.Add("data-val", "true");
context.Attributes.Add("data-val-country", ErrorMessage);
context.Attributes.Add("data-val-country-role", Value.ToString());
}
}
脚本:
@section Scripts{
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>
<script>
$.validator.addMethod('country', function (value, element, params) {
var genre = $(params[0]).val(), role = params[1], salar = value;
var selecttest = $("#Role option:selected").text();
if (selecttest == role) {
if (value.length == 0) {
console.log("selecttest == role value = null");
return false;
} else {
console.log("selecttest == role value != null");
return true;
}
} else {
console.log("selecttest != role");
return true;
}
});
$.validator.unobtrusive.adapters.add('country', ['role'], function (options) {
var element = $(options.form).find('select#Salary')[0];
options.rules['country'] = [element, options.params['role']];
options.messages['country'] = options.message;
});
</script>
}
结果:
我想在 ASP.NET MVC Core 3.1 中进行条件验证。我已经编写了自定义验证,它在服务器端验证中运行良好,但我无法执行客户端验证。在我的示例应用程序中,有一个 Salary 文本框,只有在 Roles 下拉列表中选择 Role=Teacher 时才需要它。能否请您在客户端验证部分帮助我,这是完整的示例代码。
员工模型class
public class Employee
{
public int Id { get; set; }
[Required(ErrorMessage = "Please enter name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter email")]
[EmailAddress]
public string Email { get; set; }
[Required(ErrorMessage = "Please enter role")]
[EnumDataType(typeof(Roles))]
public Roles? Role { get; set; }
[Required(ErrorMessage = "Please Enter Hire Date")]
[Display(Name = "Hire Date")]
public DateTime? HireDate { get; set; }
[RequiredIf("Role", Roles.Teacher, ErrorMessage = "Please enter salary")]
public int? Salary { get; set; }
}
角色枚举
public enum Roles
{
Student = 1,
Teacher = 2,
Assistant = 3
}
RequiredIfAttribute 自定义验证class
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
public string PropertyName { get; set; }
public object Value { get; set; }
public RequiredIfAttribute(string propertyName, object value, string errorMessage = "")
{
PropertyName = propertyName;
ErrorMessage = errorMessage;
Value = value;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var instance = validationContext.ObjectInstance;
var type = instance.GetType();
var proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if (proprtyvalue != null)
{
if (proprtyvalue.ToString() == Value.ToString() && value == null)
{
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
context.Attributes.Add("data-val", "true");
context.Attributes.Add("data-val-country", ErrorMessage);
}
}
UI
的索引视图@model ASPNETCoreValidations.Models.Employee
@using ASPNETCoreValidations.Models.enums
@{
ViewBag.Title = "Index";
}
<h1>Create</h1>
<h4>Business unit</h4>
<hr />
<div class="container">
<form asp-action="Index">
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="col-md-6">
<label asp-for="Email" class="control-label"></label>
<input asp-for="Email" class="form-control" />
<span asp-validation-for="Email" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Role" class="control-label"></label>
<select asp-for="Role" class="form-control" asp-items="Html.GetEnumSelectList<Roles>()">
<option value="">Select Department</option>
</select>
<span asp-validation-for="Role" class="text-danger"></span>
</div>
<div class="col-md-6">
<label asp-for="HireDate" class="control-label"></label>
<input asp-for="HireDate" class="form-control" />
<span asp-validation-for="HireDate" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<div class="row">
<div class="col-md-6">
<label asp-for="Salary" class="control-label"></label>
<input asp-for="Salary" class="form-control" />
<span asp-validation-for="Salary" class="text-danger"></span>
</div>
</div>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/js/RequiredIfValidate.js"></script>
}
Jquery 用于客户端验证
jQuery.validator.addMethod("requiredif",
function (value, element, param) {
// I need help here. This method never gets executed and I don't know how to implement validation here ...
// return true or false depending on the condition
});
jQuery.validator.unobtrusive.adapters.addBool("requiredif");
索引操作
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Index(Employee employee)
{
if (ModelState.IsValid)
{
RedirectToAction("Index");
}
return View();
}
根据您的描述,我建议您可以在 RequiredIfAttribute AddValidation 属性中添加一个 属性 以将角色添加到输入工资中。
那么我建议您可以尝试使用以下验证不显眼的脚本:
RequiredIfAttribute :
public class RequiredIfAttribute : ValidationAttribute, IClientModelValidator
{
public string PropertyName { get; set; }
public object Value { get; set; }
public RequiredIfAttribute(string propertyName, object value, string errorMessage = "")
{
PropertyName = propertyName;
ErrorMessage = errorMessage;
Value = value;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var instance = validationContext.ObjectInstance;
var type = instance.GetType();
var proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
if (proprtyvalue != null)
{
if (proprtyvalue.ToString() == Value.ToString() && value == null)
{
return new ValidationResult(ErrorMessage);
}
}
return ValidationResult.Success;
}
public void AddValidation(ClientModelValidationContext context)
{
context.Attributes.Add("data-val", "true");
context.Attributes.Add("data-val-country", ErrorMessage);
context.Attributes.Add("data-val-country-role", Value.ToString());
}
}
脚本:
@section Scripts{
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.1/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>
<script>
$.validator.addMethod('country', function (value, element, params) {
var genre = $(params[0]).val(), role = params[1], salar = value;
var selecttest = $("#Role option:selected").text();
if (selecttest == role) {
if (value.length == 0) {
console.log("selecttest == role value = null");
return false;
} else {
console.log("selecttest == role value != null");
return true;
}
} else {
console.log("selecttest != role");
return true;
}
});
$.validator.unobtrusive.adapters.add('country', ['role'], function (options) {
var element = $(options.form).find('select#Salary')[0];
options.rules['country'] = [element, options.params['role']];
options.messages['country'] = options.message;
});
</script>
}
结果: