C# 数据批注RegularExpressionAttribute为空/空
我正在使用C# 数据批注RegularExpressionAttribute为空/空,c#,regex,asp.net-mvc,model-view-controller,data-annotations,C#,Regex,Asp.net Mvc,Model View Controller,Data Annotations,我正在使用RegularExpressionAttribute验证属性。属性需要允许长度为零的字符串、null或(仅)空格以外的任何内容。我使用的正则表达式是“^(?!^*$)^.+$” 如果值为null或空字符串,RegularExpressionAttribute.IsValid总是返回true,但我认为它应该是false(仅空格可以) 我不是正则表达式专家,但我相信表达式是可以的(如果我使用regex.IsMatch直接从我的代码验证正则表达式,空字符串将返回false-如预期的那样)。这
RegularExpressionAttribute
验证属性。属性需要允许长度为零的字符串、null或(仅)空格以外的任何内容。我使用的正则表达式是“^(?!^*$)^.+$”
如果值为null
或空字符串
,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);
}
事情不应该那么复杂。我不确定我是否理解完整的需求,但不仅仅是
“[^]”
有效吗?令人沮丧的回答:
我确信RegularExpressionAttribute中有一个bug,尽管它在正则表达式中工作得很好,但在无法使用最简单的模式之后。结果证明,数据注释验证器使正则表达式的实现变得简单,以阻止新手错误。MSDN有这样的评论:
如果属性的值为null或空字符串(“”),则
值会自动通过对
RegularExpressionAttribute属性。验证该值是否为
如果不是null或空字符串,请使用RequiredAttribute属性
因此,从技术上讲,这不是一个错误——只是一个糟糕的想法。在我的例子中,修复方法是编写一个RegularExpressionAttribute扩展来处理null/empty(我可以通过在RegularExpressionAttribute::IsValid中使用适当的正则表达式来进行验证。试试这个^(?!\s*$)。+您必须只匹配字符串的开头一次,试试
“^(?!\\s*$)+$”
。只使用[必需]有什么问题吗
属性?为什么[必需]
属性不是一个选项?对于未来的读者:使用Required
属性的问题是,要让用户友好的文本显示为模型验证错误消息,现在需要将整个字符串复制/粘贴到两个属性中。这很混乱。正确,它应该一点也不复杂!唉,不,该模式不起作用.
=== 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 **