我正在开发一个ASP.NET MVC 5.2.3自定义数据注释,以便在Visual Studio 2015中进行验证.它需要占用任意数量的字段并确保如果有一个值,它们都必须具有值;如果他们都是空的/空白,那应该没问题.
一些例子有所帮助:
> ASP.NET MVC implement custom validator use IClientValidatable
> MVC Form Validation on Multiple Fields
> http://www.macaalay.com/2014/02/24/unobtrusive-client-and-server-side-age-validation-in-mvc-using-custom-data-annotations/
但是,我不确定如何进行客户端验证,其中您验证了未知数量的字段.
如何使用IClientValidatable接口的GetClientValidationRules()方法实现将其传递给客户端?
另外,如何将此新数据注释应用于视图模型的属性?它看起来像这样吗?
[MultipleRequired("AppNumber","UserId",/* more fields */),ErrorMessage = "Something..."] [DisplayName("App #")] public int AppNumber { get; set; } [DisplayName("User ID")] public int UserId { get; set; }
这就是我可以使用MultipleRequiredAttribute自定义数据注释类:
public class MultipleRequiredAttribute : ValidationAttribute,IClientValidatable { private readonly string[] _fields; public MultipleRequiredAttribute(params string[] fields) { _fields = fields; } protected override ValidationResult IsValid(object value,ValidationContext validationContext) { // If any field has value,then all must have value var anyHasValue = _fields.Any(f => !string.IsNullOrEmpty(f)); if (!anyHasValue) return null; foreach (var field in _fields) { var property = validationContext.ObjectType.GetProperty(field); if (property == null) return new ValidationResult($"Property '{field}' is undefined."); var fieldValue = property.GetValue(validationContext.ObjectInstance,null); if (string.IsNullOrEmpty(fieldValue?.ToString())) return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); } return null; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,ControllerContext context) { yield return new ModelClientValidationRule { ErrorMessage = ErrorMessage,ValidationType = "multiplerequired" }; } }
谢谢.
解决方法
为了获得客户端验证,您需要使用规则ValidationParameters属性的.Add()方法传递ModelClientValidationRule中“其他属性”的值,然后编写客户端脚本以将规则添加到$.validator.
但首先,您的属性还需要解决其他一些问题.首先,只有在应用属性的属性值为null时才应执行foreach循环.其次,如果其中一个“其他属性”不存在,则返回ValidationResult会让用户感到困惑和无意义,您应该忽略它.
属性代码应该是(注意我更改了属性的名称)
public class RequiredIfAnyAttribute : ValidationAttribute,IClientValidatable { private readonly string[] _otherProperties; private const string _DefaultErrorMessage = "The {0} field is required"; public RequiredIfAnyAttribute(params string[] otherProperties) { if (otherProperties.Length == 0) // would not make sense { throw new ArgumentException("At least one other property name must be provided"); } _otherProperties = otherProperties; ErrorMessage = _DefaultErrorMessage; } protected override ValidationResult IsValid(object value,ValidationContext validationContext) { if (value == null) // no point checking if it has a value { foreach (string property in _otherProperties) { var propertyName = validationContext.ObjectType.GetProperty(property); if (propertyName == null) { continue; } var propertyValue = propertyName.GetValue(validationContext.ObjectInstance,null); if (propertyValue != null) { return new ValidationResult(FormatErrorMessage(validationContext.DisplayName)); } } } return ValidationResult.Success; } public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,ControllerContext context) { var rule = new ModelClientValidationRule { ValidationType = "requiredifany",ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),}; / pass a comma separated list of the other propeties rule.ValidationParameters.Add("otherproperties",string.Join(",",_otherProperties)); yield return rule; } }
然后脚本将是
sandtrapValidation = { getDependentElement: function (validationElement,dependentProperty) { var dependentElement = $('#' + dependentProperty); if (dependentElement.length === 1) { return dependentElement; } var name = validationElement.name; var index = name.lastIndexOf(".") + 1; var id = (name.substr(0,index) + dependentProperty).replace(/[\.\[\]]/g,"_"); dependentElement = $('#' + id); if (dependentElement.length === 1) { return dependentElement; } // Try using the name attribute name = (name.substr(0,index) + dependentProperty); dependentElement = $('[name="' + name + '"]'); if (dependentElement.length > 0) { return dependentElement.first(); } return null; } } $.validator.unobtrusive.adapters.add("requiredifany",["otherproperties"],function (options) { var element = options.element; var otherNames = options.params.otherproperties.split(','); var otherProperties = []; $.each(otherNames,function (index,item) { otherProperties.push(sandtrapValidation.getDependentElement(element,item)) }); options.rules['requiredifany'] = { otherproperties: otherProperties }; options.messages['requiredifany'] = options.message; }); $.validator.addMethod("requiredifany",function (value,element,params) { if ($(element).val() != '') { // The element has a value so its OK return true; } var isValid = true; $.each(params.otherproperties,item) { if ($(this).val() != '') { isValid = false; } }); return isValid; });
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。