使用 DataType
Attribute 有什么区别?并传入值 DataType.Phone
和 Phone
Attribute它继承自 DataType
并自动设置 DataType.Phone
?
这两个类有什么区别吗?
class Person {
<b>[DataType(DataType.PhoneNumber)]</b>
public string PhoneNumber {get;set;}
}
class Person {
<b>[Phone]</b>
public string PhoneNumber {get;set;}
}
最佳答案
TLDR:[Phone]
提供验证逻辑,而 [DataType]
不提供
继承链是这样的:
属性
↳ 验证属性
↳ 数据类型属性
↳ 电话属性
所以两者都是 ValidationAttribute
的实例,但是两者都不提供开箱即用的验证。 DataType 基类仅提供用于分配 enum DataType
的结构,并将覆盖验证留给调用者
DataType
- 根据文档:
When you apply the
DataTypeAttribute
attribute to a data field you must do the following:
- Issue validation errors as appropriate.
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 中已弃用 this change description ,可能是由于 Regular Expression Best Practices 中列出的注入(inject)/安全问题来自不受约束的输入。
如果您想继续使用正则表达式验证,您必须在 .config
的 configuration
> appsettings
部分中设置以下内容> 文件:
<add key="dataAnnotations:dataTypeAttribute:disableRegEx" value="false"/>
测试项目包括根据 PhoneAttributeTests.cs 应该通过/失败的输入示例这是一个Regexr page如果您想针对(已弃用的)正则表达式验证引擎测试匹配输入。
以下是不同 .NET 风格的源代码和文档的一些链接:
| .NET Core | .NET Core 2.1 | .NET 4.7.2 | .NET |
------------------|-------------------|----------------|-----------------|----------------|
<b>DataTypeAttribute</b> | <a href="https://github.com/dotnet/corefx/blob/v2.1.5/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/DataTypeAttribute.cs" rel="noreferrer noopener nofollow">github.com/dotnet</a> | <a href="https://source.dot.net/#System.ComponentModel.Annotations/System/ComponentModel/DataAnnotations/DataTypeAttribute.cs" rel="noreferrer noopener nofollow">source.dot.net</a> | <a href="https://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/DataTypeAttribute.cs" rel="noreferrer noopener nofollow">referencesource</a> | <a href="https://learn.microsoft.com/en-us/dotnet/api/System.ComponentModel.DataAnnotations.DataTypeAttribute" rel="noreferrer noopener nofollow">docs.microsoft</a> |
<b>PhoneAttribute</b> | <a href="https://github.com/dotnet/corefx/blob/v2.1.5/src/System.ComponentModel.Annotations/src/System/ComponentModel/DataAnnotations/PhoneAttribute.cs" rel="noreferrer noopener nofollow">github.com/dotnet</a> | <a href="https://source.dot.net/#System.ComponentModel.Annotations/System/ComponentModel/DataAnnotations/PhoneAttribute.cs" rel="noreferrer noopener nofollow">source.dot.net</a> | <a href="https://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/PhoneAttribute.cs" rel="noreferrer noopener nofollow">referencesource</a> | <a href="https://learn.microsoft.com/en-us/dotnet/api/System.ComponentModel.DataAnnotations.PhoneAttribute" rel="noreferrer noopener nofollow">docs.microsoft</a> |
注意:[Phone]
的当前文档错误地指出验证使用正则表达式,自 4.7.2+ 或 .NET 中的任何地方以来都不是这样核心,所以我有submitted this PR to update
关于c# - DataType(DataType.PhoneNumber) 和 PhoneAttribute 之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53088476/