【问题标题】:ASP.NET MVC: Implement client side validation with attribute without IClientValidatableASP.NET MVC:使用没有 IClientValidatable 的属性实现客户端验证
【发布时间】:2023-03-08 19:45:02
【问题描述】:

如何在不实现IClientValidatable 的情况下创建具有客户端验证的自定义验证属性?

System.ComponentModel.DataAnnotations.RequiredAttribute 客户端如何验证?

这样做的原因是因为我在我的视图中使用来自另一个项目中的类的对象作为模型,并且我不想将 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 在视图中为该属性呈现隐藏输入。

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

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

【问题讨论】:

    标签: asp.net-mvc validation jquery-plugins


    【解决方案1】:

    我们遇到了类似的问题。我们有一个用于创建帐户的模型,该模型在其自定义属性上使用 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 还没有找到答案,我希望这可以帮助遇到同样问题的人。

    请注意,我没有在这篇文章中包含任何 javascript,因为它不需要对使用 jQuery.validate 的自定义验证规则的标准实现进行任何更改。

    【讨论】:

    • 我花了一段时间才弄清楚 Validator 类需要进入一个仍然引用 System.Web.Mvc 的库,也就是说它不能与属性类。但是,一旦我弄清楚了,它就可以奏效了。很有帮助。
    【解决方案2】:

    除非您实现 IClientValidatable,否则您无法在客户端上进行自定义验证。为此,您还需要添加客户端脚本。

    http://msdn.microsoft.com/en-us/vs2010trainingcourse_aspnetmvccustomvalidation_topic3.aspx

    【讨论】:

    • 很抱歉,但它必须是一种方式,因为来自 DataAnnotations 的属性被 html 帮助程序识别,并且它们输出带有客户端验证所需属性的 html。我知道我必须添加客户端脚本,这不是问题。
    【解决方案3】:

    有可能,我找到了这篇关于如何做到这一点的文章: http://xhalent.wordpress.com/2011/05/12/custom-unobstrusive-jquery-validation-in-asp-net-mvc-3-using-dataannotationsmodelvalidatorprovider/

    基本上你必须在你的客户端上创建一个 DataAnnotationsModelValidator 并在 Application_Start() 中注册它。

    不要忘记,您仍然需要编写用于客户端验证的 Javascript。

    【讨论】:

      猜你喜欢
      • 2012-01-07
      • 2011-10-03
      • 2014-11-03
      • 2020-11-15
      • 2013-11-12
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 2014-07-21
      相关资源
      最近更新 更多