数据注释RegularExpressionAttribute为空/ null

时间:2015-09-29 11:02:55

标签: c# regex asp.net-mvc model-view-controller data-annotations

我使用RegularExpressionAttribute来验证属性。该属性需要允许anything but zero length string, null, or (just) spaces。我使用的正则表达式是"^(?!^ *$)^.+$"

如果值为nullan empty string,则RegularExpressionAttribute.IsValid始终返回true,但我认为它应该为false(只有空格可以正常工作)。

我没有正则表达式专家,但我相信表达式正常(如果我使用Regex.IsMatch直接从我的代码验证正则表达式,则空字符串返回false - 如预期的那样)。这是RegularExpressionAttribute的问题吗?

(我知道在这种情况下,RequiredAttribute通常是一个快速但不是一个选项)

更新

为了消除任何歧义,这里有一小段测试代码来演示:

    public class MyValueTester
    {
//      internal const string _REGEX_PATTERN = "^(?!\\s*$).+$";
//      internal const string _REGEX_PATTERN = @"^(?!\s*$)";
        internal const string _REGEX_PATTERN = @"[^ ]";



        public MyValueTester()
        {
            ProperValue = "hello";
            NullValue = null;
            SpaceValue = " ";
            LeadingSpaceValue = " hi";
            EmptyValue = "";
        }

        [RegularExpression(_REGEX_PATTERN, ErrorMessage = "To err is human")]
        public string ProperValue { get; set; }

        [RegularExpression(_REGEX_PATTERN, ErrorMessage = "To null is human")]
        public string NullValue { get; set; }

        [RegularExpression(_REGEX_PATTERN, ErrorMessage = "To space is human")]
        public string SpaceValue { get; set; }

        [RegularExpression(_REGEX_PATTERN, ErrorMessage = "To empty is human")]
        public string EmptyValue { get; set; }

        [RegularExpression(_REGEX_PATTERN, ErrorMessage = "To lead is human")]
        public string LeadingSpaceValue { get; set; }
    }

测试代码:

        MyValueTester myValueTester = new MyValueTester();

        ValidationContext validationContext = new ValidationContext(myValueTester);
        List<ValidationResult> validationResults = new List<ValidationResult>();

        Debug.WriteLine("=== Testing pattern '" + MyValueTester._REGEX_PATTERN + "' ===");

        var expectedResults = new[]
                            {
                                new {propertyName = "ProperValue", expectedPass = true},
                                new {propertyName = "LeadingSpaceValue", expectedPass = true},
                                new {propertyName = "NullValue", expectedPass = false},
                                new {propertyName = "SpaceValue", expectedPass = false},
                                new {propertyName = "EmptyValue", expectedPass = false},
                            };

        bool isMatch = Validator.TryValidateObject(myValueTester, validationContext, validationResults, true);

        foreach (var expectedResult in expectedResults)
        {
            ValidationResult validationResult = validationResults.FirstOrDefault(r => r.MemberNames.Contains(expectedResult.propertyName));
            string result = expectedResult.expectedPass ? (validationResult == null ? "Ok" : "** Expected Pass **") : (validationResult != null ? "Ok" : "** Expected Failure **");

            Debug.WriteLine("{0}: {1}", expectedResult.propertyName, result);
        }

到目前为止模式建议的结果:

=== Testing pattern '^(?!\s*$).+$' ===
ProperValue: Ok
LeadingSpaceValue: Ok
NullValue: ** Expected Failure **
SpaceValue: Ok
EmptyValue: ** Expected Failure **

=== Testing pattern '^(?!\S*$)' ===
ProperValue: ** Expected Pass **
LeadingSpaceValue: ** Expected Pass **
NullValue: ** Expected Failure **
SpaceValue: Ok
EmptyValue: ** Expected Failure **

=== Testing pattern '^(?!\s*$)' ===
ProperValue: ** Expected Pass **
LeadingSpaceValue: ** Expected Pass **
NullValue: ** Expected Failure **
SpaceValue: Ok
EmptyValue: ** Expected Failure **

=== Testing pattern '[^ ]' ===
ProperValue: ** Expected Pass **
LeadingSpaceValue: ** Expected Pass **
NullValue: ** Expected Failure **
SpaceValue: Ok
EmptyValue: ** Expected Failure **

2 个答案:

答案 0 :(得分:6)

令人沮丧的答案: 我确信在无法使最简单的模式工作之后,RegularExpressionAttribute中存在一个错误,尽管在RegEx中工作正常等等。事实证明,数据注释验证器使RegEx的实现变得迟钝,以阻止新手错误。 MSDN有这样的评论:

  

如果属性的值为null或空字符串(&#34;&#34;),则为   值自动通过验证   RegularExpressionAttribute属性。验证值是否为   不为null或空字符串,请使用RequiredAttribute属性。

技术上不是一个错误 - 只是一个糟糕的主意。在我的例子中,修复是编写一个RegularExpressionAttribute扩展来处理nulls / empty&(我可以通过使用正确的正则表达式在RegularExpressionAttribute :: IsValid中进行验证。

答案 1 :(得分:0)

它不应该那么复杂。我不确定我是否理解完整的要求,但不仅仅"[^ ]"有效吗?