Класс DataAnnotations MetadataType игнорирует свойства базового класса - PullRequest
1 голос
/ 30 сентября 2010

Я наткнулся на небольшую стену, пытаясь использовать функцию .NET DataAnnotations для обеспечения простых проверок в производном классе. Я размечаю свой класс стандартными аннотациями, включенными в .NET 4 (из пространства имен System.ComponentModel.DataAnnotations), затем использую блок проверки MS Enterprise Library v5 для обработки правил.

У меня есть ряд объектов, полученных из общего базового класса, который содержит свойства, общие для всех моих объектов. В целях проверки у меня могут быть разные правила для различных классов, производных от этого класса.

Вот упрощенный пример:

public abstract class PersonBase
{
    public int Id { get; set; }
    public string Name { get; set; }
}

[MetadataType(typeof(CustomerMD))]
public class Customer : PersonBase
{

}
[MetadataType(typeof(ManagerMD))]
public class Manager : PersonBase
{

}

public class CustomerMD
{
    [Required]
    [StringLength(20, ErrorMessage="Customer names may not be longer than 20 characters.")]
    public object Name { get; set; }
}

public class ManagerMD
{
    [Required]
    [StringLength(30, ErrorMessage = "Manager names may not be longer than 30 characters.")]
    public object Name { get; set; }
}

// calling code
var invalidCustomer = new Customer {Id=1, Name=string.Empty};
var valFactory = EnterpriseLibraryContainer.Current.GetInstance<ValidatorFactory>();
var customerValidator = valFactory.CreateValidator<Customer>();
var validationResults = customerValidator.Validate(invalidCustomer);
// validationResults.IsValid should equal False, but actually equals True.

Я обнаружил, что могу получить ожидаемые результаты проверки, если переместу аннотации к базовому классу, но тогда я потеряю способность выполнять разные требования для разных типов. Кроме того, если я добавлю специфичные для класса свойства в производный класс и предоставлю метаданные для этих свойств, я получу результаты, но только для этих свойств, а не для свойств базового класса.

Я еще не пробовал использовать предоставленные EntLib атрибуты проверки; Я бы предпочел сохранить библиотеку, в которой она живет, без зависимостей вне базовой структуры, если это вообще возможно.

Я что-то упустил или мне просто не повезло?

Ответы [ 2 ]

1 голос
/ 30 сентября 2010

Я думаю, у меня есть подходящее решение для этого.

Похоже, что класс метаданных не будет обеспечивать проверку свойств, принадлежащих суперклассу целевого объекта.Чтобы метаданные работали с этим, мне нужно было пометить свойства суперкласса как виртуальные, а затем предоставить переопределения для свойств, которые я хотел проверить.

Пример (см. Вопрос выше для исходного примера):

public abstract class PersonBase
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}
[MetadataType(typeof(CustomerMD))]
partial class Customer : PersonBase
{
    public override string Name
    {
        get
        {
            return base.Name;
        }
        set
        {
            base.Name = value;
        }
    }
}

При наличии переопределения валидатор работает как положено.Это немного больше работы, но она сделает работу.

Я также попытался добавить аннотации к базовому классу в качестве запасных правил по умолчанию;это позволяет мне иметь базовый набор правил и переопределять их по мере необходимости в каждом конкретном случае.Хорошо выглядит.

0 голосов
/ 05 апреля 2016

Я столкнулся с той же проблемой и не смог сделать так, чтобы она аннотировала базовый класс с Атрибутами, используя MethadataType. Как и Scroll Lock, я сделал основную часть для виртуальных свойств базового класса. Вдобавок к этому я сделал «слежку» за не виртуальными свойствами.

public class BaseClass
{
  public virtual int Id {get;set;}

  public string Name {get;set;}
}


public class DerivedClass
{
   [SomeAttribute]
   public ovveride int Id {get{ return base.Id;} set{ base.Id = value;}}

   [SomeAttribute]
   public new string Name {get{ return base.Name;} set{ base.Name = value;}}
}
...