【问题标题】:What's the difference between DataType(DataType.PhoneNumber) & PhoneAttributeDataType(DataType.PhoneNumber) & PhoneAttribute 有什么区别
【发布时间】:2019-04-04 22:07:15
【问题描述】:

使用DataType Attribute 和传入DataType.Phone 的值与从DataType 继承并自动设置DataType.PhonePhone Attribute 有什么区别?

这两个类有什么区别吗?

class Person {
   [DataType(DataType.PhoneNumber)]
   public string PhoneNumber {get;set;}
}
class Person {
   [Phone]
   public string PhoneNumber {get;set;}
}

【问题讨论】:

    标签: c# .net data-annotations validationattribute


    【解决方案1】:

    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@

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-06
      • 2016-12-01
      • 2020-08-28
      • 2012-05-01
      • 2010-10-02
      • 2011-12-12
      相关资源
      最近更新 更多