Учитывая этот класс 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 - нет?