В чем разница между DataType (DataType.PhoneNumber) и PhoneAttribute - PullRequest
0 голосов
/ 31 октября 2018

В чем разница между использованием DataType атрибута и передачей значения DataType.Phone и Phone атрибута , который наследуется от 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;}
}

1 Ответ

0 голосов
/ 31 октября 2018

TLDR : [Phone] обеспечивает логику проверки, в то время как [DataType] не

Цепочка наследования выглядит так:

Attribute
101 ValidationAttribute
101 DataTypeAttribute
101 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 для этого описания изменения , вероятно, из-за проблем с внедрением / безопасностью, изложенных в Рекомендации по регулярным выражениям из неограниченного ввода.

Если вы хотите продолжить использовать проверку регулярных выражений, вам необходимо установить следующее в разделе configuration> appsettings вашего .config файла:

<add key="dataAnnotations:dataTypeAttribute:disableRegEx" value="false"/>

Тестовый проект включает в себя пример того, какие входные данные должны пройти / потерпеть неудачу в соответствии с PhoneAttributeTests.cs , и вот страница Regexr , если вы хотите проверить соответствие входных данных ((устарело) ) механизм проверки правильности регулярных выражений.


Вот несколько ссылок на исходный код и документацию для различных разновидностей .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">github.com/dotnet</a> | <a href="https://source.dot.net/#System.ComponentModel.Annotations/System/ComponentModel/DataAnnotations/DataTypeAttribute.cs" rel="noreferrer">source.dot.net</a> | <a href="https://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/DataTypeAttribute.cs" rel="noreferrer">referencesource</a> | <a href="https://docs.microsoft.com/en-us/dotnet/api/System.ComponentModel.DataAnnotations.DataTypeAttribute" rel="noreferrer">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">github.com/dotnet</a> | <a href="https://source.dot.net/#System.ComponentModel.Annotations/System/ComponentModel/DataAnnotations/PhoneAttribute.cs" rel="noreferrer">source.dot.net</a> | <a href="https://referencesource.microsoft.com/#System.ComponentModel.DataAnnotations/DataAnnotations/PhoneAttribute.cs" rel="noreferrer">referencesource</a> | <a href="https://docs.microsoft.com/en-us/dotnet/api/System.ComponentModel.DataAnnotations.PhoneAttribute" rel="noreferrer">docs.microsoft</a> |

Примечание : В текущих документах для [Phone] ошибочно отмечается, что при проверке используются регулярные выражения, чего не было в версии 4.7.2+ или где-либо еще в ядре .NET, поэтому я отправил этот PR для обновления

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...