【问题标题】:RequiredAttribute with AllowEmptyString=true in ASP.NET MVC 3 unobtrusive validationASP.NET MVC 3 不显眼验证中 AllowEmptyString=true 的RequiredAttribute
【发布时间】:2011-09-20 04:44:33
【问题描述】:

如果我的视图模型中有[Required(AllowEmptyStrings = true)] 声明,则验证总是在空输入时触发。我找到了the article,这解释了它发生的原因。你知道是否有可用的修复程序吗?如果没有,你是怎么处理的?

【问题讨论】:

    标签: validation asp.net-mvc-3 jquery-validate unobtrusive-javascript unobtrusive-validation


    【解决方案1】:

    注意:我假设您有 AllowEmptyStrings = true 因为您还在 Web 场景之外使用您的视图模型;否则,在 Web 场景中拥有允许空字符串的 Required 属性似乎没有多大意义。

    分三个步骤来处理:

    1. 创建一个添加该验证参数的自定义属性适配器
    2. 将您的适配器注册为适配器工厂
    3. 覆盖 jQuery 验证函数以在该属性存在时允许空字符串

    第 1 步:自定义属性适配器

    我修改了RequiredAttributeAdapter 以添加该逻辑:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Web.Mvc;
    
    namespace CustomAttributes
    {
        /// <summary>Provides an adapter for the <see cref="T:System.Runtime.CompilerServices.RequiredAttributeAttribute" /> attribute.</summary>
        public class RequiredAttributeAdapter : DataAnnotationsModelValidator<RequiredAttribute>
        {
            /// <summary>Initializes a new instance of the <see cref="T:System.Runtime.CompilerServices.RequiredAttributeAttribute" /> class.</summary>
            /// <param name="metadata">The model metadata.</param>
            /// <param name="context">The controller context.</param>
            /// <param name="attribute">The required attribute.</param>
            public RequiredAttributeAdapter(ModelMetadata metadata, ControllerContext context, RequiredAttribute attribute)
                : base(metadata, context, attribute)
            {
            }
            /// <summary>Gets a list of required-value client validation rules.</summary>
            /// <returns>A list of required-value client validation rules.</returns>
            public override IEnumerable<ModelClientValidationRule> GetClientValidationRules()
            {
                var rule = new ModelClientValidationRequiredRule(base.ErrorMessage);
                if (base.Attribute.AllowEmptyStrings)
                {
                    //setting "true" rather than bool true which is serialized as "True"
                    rule.ValidationParameters["allowempty"] = "true";
                }
    
                return new ModelClientValidationRequiredRule[] { rule };
            }
        }
    }
    

    第 2 步。在您的 global.asax / Application_Start() 中注册它

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
    
            DataAnnotationsModelValidatorProvider.RegisterAdapterFactory(typeof(RequiredAttribute),
              (metadata, controllerContext, attribute) => new CustomAttributes.RequiredAttributeAdapter(metadata,
                controllerContext, (RequiredAttribute)attribute)); 
    
            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }
    

    第 3 步。覆盖 jQuery“必需”验证函数

    这是使用 jQuery.validator.addMethod() 调用完成的,添加我们的自定义逻辑,然后调用原始函数 - 您可以阅读有关此方法的更多信息 here。如果您在整个站点中使用它,可能在您的 _Layout.cshtml 引用的脚本文件中。这是一个示例脚本块,您可以放入页面进行测试:

    <script>
    jQuery.validator.methods.oldRequired = jQuery.validator.methods.required;
    
    jQuery.validator.addMethod("required", function (value, element, param) {
        if ($(element).attr('data-val-required-allowempty') == 'true') {
            return true;
        }
        return jQuery.validator.methods.oldRequired.call(this, value, element, param);
    },
    jQuery.validator.messages.required // use default message
    );
    </script>
    

    【讨论】:

    • 感谢您的努力,乔恩!不幸的是它对我不起作用,我仍然看到“字段是必需的”消息:(我仔细检查了您的代码是否使用 VS 和浏览器调试器执行,并且我没有任何可能干扰的自定义脚本或验证相关代码。我使用jQuery 1.4.1. 这会是问题吗?
    • 是的,你说得对,我需要 Web 场景之外的功能(我的应用程序服务层执行类似的验证检查以保持 DRY)。
    • +1 这似乎是一个不错的解决方案,我想知道为什么它不起作用。但也许你可以简化它,如果你在 AllowEmptyStrings 的情况下在适配器中没有返回验证规则(空数组)。然后,您可以省去客户端的魔力。然后,您还可以轻松检查输入中是否正确省略了所需的属性。如果还是不行,就调试一下适配器代码,看看调用是否合适(如果注册没问题的话)。
    • 这有“在我的机器上工作”的承诺;-) 我列出的脚本块是在调用 /Scripts/jquery.validate.js 和 /Scripts/jquery.validate.unobtrusive 之后立即出现的。 js。我正在使用带有 jQ​​uery 1.5.1 的新 MVC 3 项目。我将尝试发布示例项目,以便您进行比较。
    • 我很好奇 - 什么不起作用?它是 Javascript 参考吗?
    【解决方案2】:

    我没有使用“必需”属性来装饰值,而是使用以下内容。我发现这是解决这个问题的最简单的方法。

    [DisplayFormat(ConvertEmptyStringToNull=false)]

    【讨论】:

    • 我同意 - 这似乎是处理这个问题的最简单方法。如果要允许空字符串,只需在保存前将控制器中的 null 改回 "" 即可!
    • 漂亮! [Required] 的这个缺点多年来一直困扰着我在多个 asp.net 网站上。(我现在同时使用 [Required(AllowEmptyStrings = true)、DisplayFormat(ConvertEmptyStringToNull=false)] 并且效果很好。
    • 很好的答案。非常感谢。
    • +10 给 Rick 和 Mark 以缓解 MVC 空字符串的痛苦,同时使用 DisplayFormat(ConvertEmptyStringToNull=false) 和 Required(AllowEmptyStrings = true)
    猜你喜欢
    • 2011-07-09
    • 1970-01-01
    • 2011-06-28
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 2011-06-22
    相关资源
    最近更新 更多