如何在不实现IClientValidatable的情况下通过客户端验证创建自定义验证属性?
System.ComponentModel.DataAnnotations.RequiredAttribute客户端如何验证?

这样做的原因是因为我将另一个项目中的类的对象用作 View 中的模型,并且不想将System.Web.MVC引用添加到该项目。

编辑以添加更多信息:

  • 我知道IClientValidatable用于向其中添加自定义属性
    HTML,稍后将由非侵入式验证使用。
  • 我知道我需要添加javascript代码才能在中进行验证
    客户端。

  • 我不知道如何使用自定义验证属性中的信息将必要的属性添加到HTML中,以使非干扰性验证正常工作。

    这是我的自定义验证属性:
    public class RequiredGuidAttribute : ValidationAttribute
    {
        public override bool IsValid(object value)
        {
            Guid? guidValue = value as Guid?;
    
            if (guidValue == null)
                return false;
    
            return guidValue != Guid.Empty;
        }
    }
    

    这是我应用了属性的属性:
        [RequiredGuid(ErrorMessageResourceType = typeof(ClientOrderResources), ErrorMessageResourceName = "RequiredShippingMethod")]
        public Guid ShippingMethodId
        {
            get { return GetProperty(ShippingMethodIdProperty); }
            set { SetProperty(ShippingMethodIdProperty, value); }
        }
    

    最后,我使用Html.HiddenFor在 View 中呈现该属性的隐藏输入。

    现在,如何从属性中获取错误消息以将其应用于HTML?我应该使用Reflection自己做还是有更好的方法?

    然后,如何告诉Html.HiddenFor使用该信息向HTML添加必要的属性?

    最佳答案

    我们有一个类似的问题。我们有一个用于创建帐户的模型,该模型在其自定义属性上使用IClientValidatable。但是,我们创建了一个批量帐户创建过程,该过程位于我们无法引用System.Web.Mvc的网站之外。因此,当我们调用Validator.TryValidateObject时,从IClientValidatable继承的任何自定义验证器都非常简单跳过了。我们正在与之合作的未能在我们网站之外进行验证的原因是:

    public class AgeValidatorAttribute : ValidationAttribute, IClientValidatable
    {
        public int AgeMin { get; set; }
        public int AgeMax { get; set; }
    
        public override bool IsValid(object value)
        {
            //run validation
        }
    }
    
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = ErrorMessageString,
                ValidationType = "agevalidator"
            };
    
            rule.ValidationParameters["agemin"] = AgeMin;
            rule.ValidationParameters["agemax"] = AgeMax;
    
            yield return rule;
        }
    

    删除System.Web.Mvc要求我们也删除GetClientValidationRules和IClientValidatable引用。为了做到这一点并且仍然需要客户端验证,我们必须创建一个新类:
    public class AgeValidatorClientValidator : DataAnnotationsModelValidator<AgeValidatorAttribute>
    {
        private readonly string _errorMessage;
        private readonly string _validationType;
    
        public AgeValidatorClientValidator(ModelMetadata metadata, ControllerContext context, AgeValidatorAttribute attribute)
            : base(metadata, context, attribute)
        {
            this._errorMessage = attribute.FormatErrorMessage(metadata.DisplayName);
            this._validationType = "agevalidator";
        }
    
        public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
        {
            var rule = new ModelClientValidationRule
            {
                ErrorMessage = this._errorMessage,
                ValidationType = this._validationType
            };
    
            rule.ValidationParameters["agemin"] = base.Attribute.AgeMin;
            rule.ValidationParameters["agemax"] = base.Attribute.AgeMax;
    
            yield return rule;
        }
    }
    

    如您所见,它的功能与以前基本相同,只是使用DataAnnatotationsModelValidator而不是IClientValidatable来完成的。我们还需要执行一步,将DataAnnotationsModelValidator实际附加到属性上,这是在Global.asax.cs Application_Start方法中完成的
    DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(AgeValidatorAttribute), typeof(AgeValidatorClientValidator));
    现在,您可以像使用普通属性一样使用它:
    [AgeValidator(AgeMax = 110, AgeMin = 18, ErrorMessage = "The member must be between 18 and 110 years old")]
    public string DateOfBirth { get; set; }
    

    我知道这个问题已经有一年历史了,但是我昨天和一天的一半时间都在努力解决这个问题。因此,我希望这对遇到同样问题的人有所帮助,如果OP尚未找到答案的话。

    请注意,由于本文不需要使用jQuery.validate自定义验证规则的标准实现进行任何更改,因此在本文中未包含任何JavaScript。

    关于asp.net-mvc - ASP.NET MVC : Implement client side validation with attribute without IClientValidatable,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14283216/

    10-09 02:09