使用 AttributeTargets.Class 对自定义 ValidationAttribute 进行客户端验证



是否可以为类范围中使用的自定义 ValidationAttribute 实现客户端站点验证?例如,我的MaxLengthGlobal,它应该确保所有输入字段的全局最大限制。

[AttributeUsage(AttributeTargets.Class)]
public class MaxLengthGlobalAttribute : ValidationAttribute, IClientValidatable
{
    public int MaximumLength
    {
        get;
        private set;
    }
    public MaxLengthGlobalAttribute(int maximumLength)
    {
        this.MaximumLength = maximumLength;
    }
    public override bool IsValid(object value)
    {
        var properties = TypeDescriptor.GetProperties(value);
        foreach (PropertyDescriptor property in properties)
        {
            var stringValue = property.GetValue(value) as string;
            if (stringValue != null && (stringValue.Length > this.MaximumLength))
            {
                return false;
            }
        }
        return true;
    }
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {       
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = this.FormatErrorMessage(metadata.GetDisplayName()),
            ValidationType = "maxlengthglobal",
        };
        rule.ValidationParameters.Add("maxlength", this.MaximumLength);         
        yield return rule;
    }
}

谢谢。

我在寻找相同问题的解决方案时找到了这个答案,并提出了解决方法。

而不是 1 个验证属性,有 2

1.( ServerValidationAttribute 将位于类上,并且不会实现 IClientValidatable。

[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class MyCustomServerValidationAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        // remember to cast to the class type, not property type
        // ... return true or false
    }
}

2.( ClientValidationAttribute 将位于字段/属性上,并将实现 IClientValidatable,但 IsValid 覆盖始终返回 true。

[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, 
    AllowMultiple = false, Inherited = true)]
public class MyCustomClientValidationAttribute : ValidationAttribute, 
    IClientValidatable
{
    public override bool IsValid(object value)
    {
        return true;
    }
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(
        ModelMetadata metadata, ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ErrorMessage = ErrorMessage,
            ValidationType = "mycustomvalidator",
        };
        var viewContext = (ViewContext)context;
        var dependentProperty1 = viewContext.ViewData.TemplateInfo
            .GetFullHtmlFieldId("DependentProperty1");
        //var prefix = viewContext.ViewData.TemplateInfo.HtmlFieldPrefix;
        rule.ValidationParameters.Add("dependentproperty1", dependentProperty1);
        yield return rule;
    }
}

在客户端上执行时,将忽略服务器属性,反之亦然。

如果需要在类上具有验证属性,则验证可能会针对多个字段进行。我删除了一些样板代码,用于将其他参数传递给客户端验证方法,但它没有按预期工作。在我的实际代码中,我已经注释掉了viewContext和dependentProperty1变量,并且只是将"DependentProperty1"字符串传递给规则的第二个参数。ValidationParameters.Add 方法。由于某种原因,我得到了不正确的 HtmlField前缀。如果有人可以帮助解决这个问题,请发表评论...

无论如何,你最终会得到一个这样的视图模型:

[MyCustomServerValidation(ErrorMessage = MyCustomValidationMessage)]
public class MyCustomViewModel
{
    private const string MyCustomValidationMessage = "user error!";
    [Display(Name = "Email Address")]
    [MyCustomClientValidation(ErrorMessage = MyCustomValidationMessage)]
    public string Value { get; set; }
    [HiddenInput(DisplayValue = false)]
    public string DependentProperty1 { get; set; }
}

客户端脚本如下所示:

/// <reference path="jquery-1.6.2.js" />
/// <reference path="jquery.validate.js" />
/// <reference path="jquery.validate.unobtrusive.js" />
$.validator.addMethod('mycustomvalidator', function (value, element, parameters) {
    var dependentProperty1 = $('#' + parameters['dependentproperty1']).val();
    // return true or false
});
$.validator.unobtrusive.adapters.add('mycustomvalidator', ['dependentproperty1'], 
    function (options) {
        options.rules['mycustomvalidator'] = {
            dependentproperty1: options.params['dependentproperty1']
        };
        options.messages['mycustomvalidator'] = options.message;
    }
);

还有这样的视图:

@Html.EditorFor(m => m.Value)
@Html.EditorFor(m => m.DependentProperty1)
@Html.ValidationMessageFor(m => m.Value)
@Html.ValidationMessageFor(m => m)

然后,如果禁用了客户端验证,则会显示@Html.ValidationMessageFor(m => m),而不是属性的。

不,这是不可能的。不好意思。

相关内容

  • 没有找到相关文章

最新更新