在ASP.NET MVC 3中,AllowEmptyString = true的RequiredAttribute不显眼的验证

Use*_*rol 21 validation unobtrusive-javascript jquery-validate unobtrusive-validation asp.net-mvc-3

如果我[Required(AllowEmptyStrings = true)]在视图模型中有声明,则始终在空输入上触发验证.我发现这篇文章解释了它为什么会发生.你知道是否有修复方法吗?如果没有,你如何处理它?

Jon*_*way 22

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

处理此问题有三个步骤:

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

第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 };
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

步骤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);
    }
Run Code Online (Sandbox Code Playgroud)

第3步.覆盖jQuery"必需"验证功能

这是使用jQuery.validator.addMethod()调用,添加我们的自定义逻辑然后调用原始函数完成的 - 您可以在此处阅读有关此方法的更多信息.如果您在整个站点中使用它,可能在从_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>
Run Code Online (Sandbox Code Playgroud)


Ric*_*hur 15

我没有使用'Required'属性来装饰值,而是使用以下内容.我觉得这是解决这个问题最简单的方法.

[DisplayFormat(ConvertEmptyStringToNull =假)]

  • 美丽![Required]的这个缺点让我在多个asp.net网站上烦恼了多年.(我现在使用[Required(AllowEmptyStrings = true),DisplayFormat(ConvertEmptyStringToNull = false)]并且效果很好. (2认同)