2010-12-04 3 views
2

J'utilise la validation des métadonnées pour mon MVC et SIlverlight ensemble. Cependant, les classes pour silverlight ne fonctionnent pas, et je pense que c'est dû au MetadataTypeAttribute qui n'existe pas pour silverlight 4. Cela semble être la seule chose qui retient cette partie de mon projet ... J'essaie d'éviter de faire tout ça coutume que je n'aime pas réinventer la roue, mais les classes de validation ne semblent rendre les résultats escomptés ..:Utilisation de Silvlight, EF POCO personnalisé, Validation personnalisée - exploitation des métadonnées et ne fonctionne pas dans Silverlight 4

Voici ma solution pour CLR:

var metadataAttrib = this.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault(); 
      var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : this.GetType(); 
      var buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast<PropertyDescriptor>(); 
      var modelClassProperties = TypeDescriptor.GetProperties(this.GetType()).Cast<PropertyDescriptor>(); 

     var brokenRules = from buddyProp in buddyClassProperties 
          join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name 
          from attribute in buddyProp.Attributes.OfType<ValidationAttribute>() 
          where !attribute.IsValid(modelProp.GetValue(this)) 
          select new BrokenRule() { FieldName = buddyProp.Name, ErrorMessage = attribute.FormatErrorMessage("") }; 

     brokenRulesList = brokenRules.ToList(); 

... Et voici le code pour Silverlight

var metadataAttrib = this.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault(); 
      var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : this.GetType(); 
      var buddyClassProperties = buddyClassOrModelClass.GetType().GetProperties(); 
      var modelClassProperties = this.GetType().GetProperties(); 

      var validationContext = new ValidationContext(this, null, null); 

      var validationResults = from buddyProp in buddyClassProperties 
           join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name 
           from attribute in buddyProp.GetCustomAttributes(true).OfType<ValidationAttribute>().Cast<ValidationAttribute>() 
           where buddyProp.Name == modelProp.Name 
           select attribute.GetValidationResult(modelProp, validationContext); 

      brokenRulesList = new List<BrokenRule>(); 
      foreach (ValidationResult vr in validationResults) 
      { 
       foreach (string memberName in vr.MemberNames) 
        brokenRulesList.Add(new BrokenRule() { FieldName = memberName, ErrorMessage = vr.ErrorMessage }); 

      } 

... Cependant, le code silverlight ne fonctionne pas .. Voici le cas de test ...

[MetadataType(typeof(UserMetadata))] 
    public partial class User 
    { 
     public partial class UserMetadata 
     { 

     [Required(ErrorMessageResourceName = "UserIDValidationMessage", ErrorMessageResourceType = typeof(AppResources))] 
      public System.Guid ID { get; set; } 

      public Nullable<int> UID { get; set; } 

     [Display(Name="UserUsernameLabel", Description="Username", ResourceType=typeof(AppResources))] 
     [Required(ErrorMessageResourceName = "UserUsernameValidationMessage", ErrorMessageResourceType = typeof(AppResources))] 
     [StringLength(70, ErrorMessageResourceName="UserUsernameValidationMessage", ErrorMessageResourceType = typeof(AppResources))] 
      public string Username { get; set; } 

     [Display(Name="UserFirstNameLabel", Description="First Name", ResourceType=typeof(AppResources))] 
     [StringLength(90, ErrorMessageResourceName="UserFirstNameValidationMessage", ErrorMessageResourceType = typeof(AppResources))] 
      public string FirstName { get; set; } 
} 

J'ai fait une classe pour silverlight qui permet de le compiler, mais sa ne fonctionne pas - comme prévu ..

using System; 
using System.Reflection; 

namespace System.ComponentModel.DataAnnotations 
{ 
    public class MetadataTypeAttribute : Attribute 
    { 
     public MetadataTypeAttribute(Type t) 
     { 
      MetadataClassType = t; 
     } 

     public Type MetadataClassType 
     { 
      get; 
      set; 
     } 

    } 
} 

Est-ce que quelqu'un sait comment tirer parti de simplement aux classes de métadonnées pour silverlight? Pourquoi le métadatatypeat n'est pas là je ne sais pas. Aucune suggestion?

Répondre

0

Si vous souhaitez utiliser d'attributs de validation dans Silverlight, vous devez faire une des trois choses:

  1. Utilisez un DataGrid boîte à outils pour afficher les données - cela valide automatiquement vos propriétés (je l'ai vu d'autres contrôles Pour ce faire, tel que RadGridView de Telerik)

  2. Validez manuellement dans le setter de propriété et lancez une exception ValidationException si la valeur n'est pas valide. Vous devez également définir ValidatesOnExceptions et NotifyOnValidationError sur true dans vos liaisons.

  3. Implement INotifyDataErrorInfo or IDataError dans votre modèle et de définir des erreurs de validation via les méthodes de ces interfaces.

L'option 3 est l'approche recommandée et semble être la plus adaptée à vos besoins.

Consultez ce lien pour plus d'infos msdn.microsoft.com/en-us/library/dd901590(v=vs.95).aspx~~V~~singular~~3rd

Enfin, l'interface peut INotifyDataErrorInfo être un peu intimidant - il y a beaucoup de plomberie à trier avant de pouvoir l'utiliser. Cependant, this post de Jeremy Likness pourrait aider un peu. Notez que vous n'avez pas à valider dans le setter comme dans l'exemple.

Questions connexes