TLDR:[Phone] 提供验证逻辑,而 [DataType] 不提供
继承链如下所示:
Attribute
↳ ValidationAttribute
↳ DataTypeAttribute
↳PhoneAttribute
所以两者都是ValidationAttribute 的实例,但是两者都不提供开箱即用的验证。 DataType 基类只提供分配enum DataType 的结构,并将覆盖验证留给调用者
DataType - 根据文档:
当您将DataTypeAttribute 属性应用于数据字段时,您必须执行以下操作:
DataType - 根据源码:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Parameter, AllowMultiple = false)]
public class DataTypeAttribute : ValidationAttribute
{
/// <summary> Override of <see cref="ValidationAttribute.IsValid(object)" /> </summary>
/// <remarks>This override always returns <c>true</c>. Subclasses should override this to provide the correct result.</remarks>
/// <param name="value">The value to validate</param>
/// <returns>Unconditionally returns <c>true</c></returns>
/// <exception cref="InvalidOperationException"> is thrown if the current attribute is ill-formed.</exception>
public override bool IsValid(object value)
{
EnsureValidDataType();
return true;
}
}
旁白:由于您需要覆盖IsValid,我不确定为什么.NET 没有将类和属性标记为abstract 以保证以编程方式实现。
PhoneAttribute - 验证逻辑
因此,如果您确实想提供验证,并且您使用的是 .NET 4.5+ 或 .NET Core,则可以使用 [Phone] 属性,但验证机制也会随着时间而改变,您也可以对于什么构成您的业务流程的有效输入,有一套不同的规则。
.NET Framework 最初使用以下正则表达式:
const string pattern = @"^(\+\s?)?((?<!\+.*)\(\+?\d+([\s\-\.]?\d+)?\)|\d+)([\s\-\.]?(\(\d+([\s\-\.]?\d+)?\)|\d+))*(\s?(x|ext\.?)\s?\d+)?$";
但这在 .NET Framework 4.7.2 per this change description 中已被弃用,可能是由于 Regular Expression Best Practices 中来自不受约束的输入的注入/安全问题。
如果您想继续使用正则表达式验证,您必须在 .config 文件的 configuration > appsettings 部分设置以下内容:
<add key="dataAnnotations:dataTypeAttribute:disableRegEx" value="false"/>
Test 项目包含一个示例,其中包含根据 PhoneAttributeTests.cs 应该通过/失败的输入的示例,如果您想针对(已弃用的)正则表达式验证引擎测试匹配输入,这里是 Regexr page。
以下是不同风格 .NET 的源代码和文档的一些链接:
| .NET Core | .NET Core 2.1 | .NET 4.7.2 | .NET |
------------------|-------------------|----------------|-----------------|----------------|
DataTypeAttribute | @987654326@ | @987654327@ | @987654328@ | @987654329@ |
PhoneAttribute | @987654330@ | @987654331@ | @987654332@ | @987654333@ |
注意:[Phone] 的当前文档错误地指出验证使用正则表达式,自 4.7.2+ 或 .NET 核心中的任何地方以来都不是这样,所以我 @ 987654334@