开发者

.NET ComponentModel.DataAnnotations issue with RegularExpression attribute

开发者 https://www.devze.com 2023-04-12 08:14 出处:网络
I have to validate a string that\'s supposed to contain an hour number (e.g. 00 to 23). I hence set an annotation like:

I have to validate a string that's supposed to contain an hour number (e.g. 00 to 23).

I hence set an annotation like:

 [RegularExpression("[01]?[0-9]|2[0-3]", ErrorMessage = "Error")]
 public string JobStartHour {...}

Unfortunately, this regex doesn't match the inputs from 20 to 23, as it's supposed to do (IMHO).

Doesn't this RegularExpression attribute use the plain old Regex.IsMatch ?

Regex.IsMatch("22", "[01]开发者_如何学编程?[0-9]|2[0-3]")

returns true...

Edit: I know, using a string isn't the best idea so as to store a number, nevertheless, this regex issue is annoying.


This pattern will work. I ran into the same thing. It has to do with using parens to correctly establish the groupings. If the RegExAttribute can't figure it out, it seems to just quit at the pipe symbol.

Here's a unit test.

    [TestMethod]
    public void CheckHours()
    {
      var pattern = "([0-1][0-9])|(2[0-3])|([0-9])";
      int cnt = 0;

      var hours = new string[]
        { "1","2","3","4","5","6","7","8","9",
          "01","02","03","04","05","06","07","08","09",
          "10","11","12","13","14","15","16","17","18","19",
          "20","21","22","23" };

      var attribute = new RegularExpressionAttribute(pattern);
      bool isMatchOk = false;
      bool isAttrOk = false;

      foreach (var hour in hours)
      {
        isMatchOk = System.Text.RegularExpressions.Regex.IsMatch(hour, pattern);
        isAttrOk = attribute.IsValid(hour);

        if (isMatchOk & isAttrOk)
        { cnt += 1; }
        else
        { Debug.WriteLine(hour + " / " 
          + isMatchOk.ToString() + " / "
          + isAttrOk.ToString()); }
      }

      Assert.AreEqual(32, cnt);
    }


Try this:

[RegularExpression("2[0-3]|[01]?[0-9]", ErrorMessage = "Error")]
 public string JobStartHour {...}


Don't know why this regex isn't correctly interpreted, but a solution is to implement a CustomValidation, which is pretty handy.

   [CustomValidation(typeof(MyCustomValidation), "Validate24Hour")]
     public string JobStartHour {...}

...

  public class MyCustomValidation
    {
        public static ValidationResult Validate24Hour(string candidate)
        {
            bool isValid = false;
         ...
            if (isValid)
            {
                return ValidationResult.Success;
            }
            else
            {
                return new ValidationResult("Error");
            }
        }
   }


You have to group the | to work properly.

I successfully tried, which should be exactly your regex but grouped and limited to start & end:

^([01]?[0-9]|2[0-3])$

Your named Regex.IsMatch line returns true on every expression on my machine.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号