Атрибуты DataAnnotation странности класса собеседника - ASP.NET MVC - PullRequest
4 голосов
/ 27 мая 2010

Учитывая этот класс POCO, который был автоматически сгенерирован шаблоном EntityFramework T4 (не имеет и не может быть изменен вручную каким-либо образом):

public partial class Customer
{
    [Required]
    [StringLength(20, ErrorMessage = "Customer Number - Please enter no more than 20 characters.")]
    [DisplayName("Customer Number")]
    public virtual string CustomerNumber { get;set; }

    [Required]
    [StringLength(10, ErrorMessage = "ACNumber - Please enter no more than 10 characters.")]
    [DisplayName("ACNumber")]
    public virtual string ACNumber{ get;set; }
}

Обратите внимание, что "ACNumber" - это поле базы данных с плохим именем, поэтому автогенератор не может сгенерировать правильное отображаемое имя и сообщение об ошибке, которое должно быть "Account Number".

Итак, мы вручную создаем этот класс друзей, чтобы добавить пользовательские атрибуты, которые не могут быть сгенерированы автоматически:

[MetadataType(typeof(CustomerAnnotations))]
public partial class Customer { }

public class CustomerAnnotations
{
    [NumberCode] // This line does not work
    public virtual string CustomerNumber { get;set; }

    [StringLength(10, ErrorMessage = "Account Number - Please enter no more than 10 characters.")]
    [DisplayName("Account Number")]
    public virtual string ACNumber { get;set; }
}

Где [NumberCode] - это простой атрибут на основе регулярных выражений, который допускает только цифры и дефисы:

[AttributeUsage(AttributeTargets.Property)]
public class NumberCodeAttribute: RegularExpressionAttribute
{
    private const string REGX = @"^[0-9-]+$"; 
    public NumberCodeAttribute() : base(REGX) { }
}

СЕЙЧАС, когда я загружаю страницу, атрибут DisplayName работает правильно - он показывает отображаемое имя из класса собеседника, а не сгенерированного класса.

Атрибут StringLength работает неправильно - он показывает сообщение об ошибке из сгенерированного класса («ACNumber» вместо «Номер счета»).

НО атрибут [NumberCode] в классе собеседников даже не применяется к свойству AccountNumber:

foreach (ValidationAttribute attrib in prop.Attributes.OfType<ValidationAttribute>())
{
    // This collection correctly contains all the [Required], [StringLength] attributes
    // BUT does not contain the [NumberCode] attribute
    ApplyValidation(generator, attrib);
}

Почему коллекция prop.Attributes.OfType<ValidationAttribute>() не содержит атрибут [NumberCode]? NumberCode наследует RegularExpressionAttribute, который наследует ValidationAttribute, поэтому он должен быть там.

Если вручную переместить атрибут [NumberCode] в автоматически сгенерированный класс, он будет включен в коллекцию prop.Attributes.OfType<ValidationAttribute>().

Так что я не понимаю, почему этот конкретный атрибут не работает, когда в классе собеседника, когда другие атрибуты в классе собеседника работают. И почему этот атрибут работает в автоматически сгенерированном классе, а не в приятеле. Есть идеи?

Кроме того, почему DisplayName переопределяется собеседником, а StringLength - нет?

Ответы [ 2 ]

1 голос
/ 29 июня 2010

Я заметил, что ваш NumberCodeAttribute не указывает AllowMultiple = True в атрибуте AttributeUsage.По умолчанию для этого параметра (если он не указан) установлено значение false.Попробуйте добавить это, и оно должно появиться.

1 голос
/ 22 июня 2010

Я пересоздал твой код, используя VS2008 и MVC2, и он работал нормально для меня.

...