Vma*_*man 1 c# regex model-view-controller asp.net-mvc data-annotations
我正在使用RegularExpressionAttribute验证属性.该物业需要允许anything but zero length string, null, or (just) spaces.我正在使用的正则表达式是"^(?!^ *$)^.+$".
如果值为null或an 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; }
}
Run Code Online (Sandbox Code Playgroud)
测试代码:
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);
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,模式建议的结果:
=== 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 **
Run Code Online (Sandbox Code Playgroud)
令人沮丧的答案:我确信在无法使最简单的模式工作之后,RegularExpressionAttribute中存在一个错误,尽管在RegEx中工作正常等等.事实证明,数据注释验证器使RegEx的实现变得愚蠢,以阻止新手错误.MSDN有这样的评论:
如果属性的值为null或空字符串(""),则该值会自动传递RegularExpressionAttribute属性的验证.要验证该值是否为空或空字符串,请使用RequiredAttribute属性.
所以技术上不是一个错误 - 只是一个糟糕的主意.在我的例子中,修复是编写一个RegularExpressionAttribute扩展来处理nulls/empty(我可能只需使用正确的正则表达式来验证RegularExpressionAttribute :: IsValid).
| 归档时间: |
|
| 查看次数: |
3544 次 |
| 最近记录: |