微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – ASP.NET MVC自定义多字段验证

我正在开发一个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;
});

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐