在Asp.Net MVC中实现RequiredIf标签对Model中的属性进行验证
在Asp.Net MVC中可以用继承ValidationAttribute的方式,自定制实现RequiredIf标签对Model中的属性进行验证
具体场景为:某一属性是否允许为null的验证,要根据另一个属性值是否为true来判断
代码如下所示:
1):后台代码
public class RequiredIfAttribute : ValidationAttribute, IClientValidatable { private RequiredAttribute innerAttribute = new RequiredAttribute(); public string DependentProperty { get; set; } public object TargetValue { get; set; } public RequiredIfAttribute(string dependentProperty, object targetValue) { this.DependentProperty = dependentProperty; this.TargetValue = targetValue; } protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var field = validationContext.ObjectInstance.GetType().GetProperty(DependentProperty); if (field != null) { var dependentValue = field.GetValue(validationContext.ObjectInstance, null); if (Object.Equals(dependentValue, TargetValue)) { if (!innerAttribute.IsValid(value)) return new ValidationResult(ErrorMessage); } } return ValidationResult.Success; } public virtual IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelClientValidationRule { ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()), ValidationType = "requiredif", }; string depProp = BuildDependentPropertyId(metadata, context as ViewContext); // find the value on the control we depend on; // if it's a bool, format it javascript style // (the default is True or False!) string targetValue = (TargetValue ?? "").ToString(); if (TargetValue is bool) targetValue = targetValue.ToLower(); rule.ValidationParameters.Add("dependentproperty", depProp); rule.ValidationParameters.Add("targetvalue", targetValue); yield return rule; } private string BuildDependentPropertyId(ModelMetadata metadata, ViewContext viewContext) { // build the ID of the property string depProp = viewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(DependentProperty); // unfortunately this will have the name of the current field appended to the beginning, // because the TemplateInfo's context has had this fieldname appended to it. Instead, we // want to get the context as though it was one level higher (i.e. outside the current property, // which is the containing object, and hence the same level as the dependent property. var thisField = metadata.PropertyName + "_"; if (depProp.StartsWith(thisField)) // strip it off again depProp = depProp.Substring(thisField.Length); return depProp; } }
2):前台代码
$.validator.addMethod('requiredif', function (value, element, parameters) { var id = '#' + parameters['dependentproperty']; // get the target value (as a string, // as that's what actual value will be) var targetvalue = parameters['targetvalue']; targetvalue = (targetvalue == null ? '' : targetvalue).toString(); // get the actual value of the target control // note - this probably needs to cater for more // control types, e.g. radios var control = $(id); if (control == null || control.length == 0) { // if control is null, the control is a checkbox or a radio control = $("[name='" + parameters['dependentproperty'] + "']:checked"); } var controltype = control.attr('type'); var actualvalue = (controltype === 'checkbox' || controltype === 'radio') ? control.val() != "" ? control.val() : control.prop('checked').toString() : control.val(); // if the condition is true, reuse the existing // required field validator functionality if ($.trim(targetvalue) === $.trim(actualvalue) || ($.trim(targetvalue) === '*' && $.trim(actualvalue) !== '')) return $.validator.methods.required.call( this, value, element, parameters); return true; }); $.validator.unobtrusive.adapters.add('requiredif', ['dependentproperty', 'targetvalue'], function (options) { options.rules['requiredif'] = { dependentproperty: options.params['dependentproperty'], targetvalue: options.params['targetvalue'] }; options.messages['requiredif'] = options.message; });
将标签RequiredIf添加到对应的属性上
【注:第一个参数为相关联的属性名,第二个参数表示相关联属性值(相关联属性值=第二个参数时,再对此属性进行验证),第三个参数为错误提示信息】
public class EricSunModel { public bool ContainsDangerousGoods { get; set; } [RequiredIf("ContainsDangerousGoods", true, ErrorMessage = "Please enter UN Number")] [Display(Name = "UN Number")] public string UNNumber { get; set; } }
更多细节请参考如下链接: