在Asp.Net MVC中实现RequiredIf标签对Model中的属性进行验证

时间:2022-04-18 02:12:08

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

更多细节请参考如下链接:

http://mvcdiary.com/2013/02/28/conditional-required-validation-or-field-mandatory-depends-on-another-field-mvc-4/