【问题标题】:Conditional client side validation in ASP.NET MVC Core 3.1ASP.NET MVC Core 3.1 中的条件客户端验证
【发布时间】:2021-03-15 17:39:54
【问题描述】:

我想在 ASP.NET MVC Core 3.1 中进行条件验证。我已经编写了自定义验证,它在服务器端验证中运行良好,但我无法执行客户端验证。在我的示例应用程序中,有一个 Salary 文本框,只有在 Roles 下拉列表中选择 Role=Teacher 时才需要该文本框。您能否在客户端验证部分帮助我,这是完整的示例代码。

员工模型类

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 自定义验证类

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);
        }
    }

用户界面的索引视图

@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();
        }

【问题讨论】:

    标签: asp.net-core asp.net-core-mvc asp.net-core-3.1 unobtrusive-validation client-side-validation


    【解决方案1】:

    根据您的描述,我建议您可以在RequiredIfAttribute AddValidation 属性中添加一个属性,以将角色添加到输入工资中。

    那么我建议你可以尝试使用下面的验证不显眼的脚本:

    必需的属性:

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

    结果:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-14
      • 2014-07-21
      • 1970-01-01
      • 1970-01-01
      • 2013-12-12
      • 1970-01-01
      • 2020-11-15
      • 1970-01-01
      相关资源
      最近更新 更多