2010-09-30 8 views
1

J'ai rencontré un peu de difficulté en essayant d'utiliser la fonctionnalité .NET DataAnnotations pour fournir des validations simples dans une classe dérivée. Je marque ma classe avec les annotations standard incluses dans .NET 4 (à partir de l'espace de noms System.ComponentModel.DataAnnotations), puis en utilisant le bloc de validation MS Enterprise Library v5 pour traiter les règles.DataAnnotations Classe MetadataType ignore les propriétés de classe de base

J'ai un certain nombre d'objets dérivés d'une classe de base commune, qui contient des propriétés communes à tous mes objets. À des fins de validation, je peux avoir des règles différentes pour les différentes classes dérivées de cette classe.

Voici un exemple simplifié:

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. 

J'ai trouvé que je peux obtenir les résultats de validation attendus si je pousse les annotations jusqu'à la classe de base, mais je perds la capacité de remplir des exigences différentes pour les différents les types. De plus, si je mets des propriétés spécifiques à une classe sur une classe dérivée et que je fournis des métadonnées pour ces propriétés, j'obtiens des résultats, mais seulement pour ces propriétés, pas les propriétés de la classe de base.

Je n'ai pas encore essayé d'utiliser les attributs de validation fournis par EntLib; Je préférerais que la bibliothèque reste libre de toute dépendance extérieure au cadre de base, si possible. Est-ce que je manque quelque chose ou est-ce que je n'ai pas de chance ici?

Répondre

1

Je pense que j'ai une solution réalisable pour cela.

Il semble que la classe Métadonnées ne fournisse pas de validation des propriétés appartenant à la superclasse de l'objet cible. Pour que Metadata fonctionne, il fallait marquer les propriétés de la superclasse comme virtuelles, puis fournir des remplacements pour les propriétés que je voulais valider.

Exemple (voir question ci-dessus par exemple d'origine):

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; 
     } 
    } 
} 

Avec la dérogation en place, le validateur fonctionne comme prévu. C'est un peu plus de travail, mais ça va faire le travail.

J'ai également essayé d'ajouter des annotations à la classe de base en tant que règles par défaut de secours; cela me permet d'avoir un ensemble de règles de base et de les remplacer au besoin au cas par cas. Vous cherchez bien.

0

Je rencontre le même problème et je n'ai pas réussi à faire annoter une classe de base avec des attributs en utilisant MethadataType. Comme Scroll Lock, j'ai fait la partie prioritaire pour les propriétés virtuelles de la classe de base. En plus de cela, j'ai fait des "ombrages" pour les propriétés none none.

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;}} 
 
}