Comment définir une propriété IDataErrorInfo Error pour plusieurs propriétés BO

Je commence à implémenter la validation dans mon projet WPF via l’interface IDataErrorInfo. Mon object métier contient plusieurs propriétés avec des informations de validation. Comment puis-je obtenir une liste de TOUS les messages d’erreur associés à l’object. Ma pensée est que c’est la raison pour laquelle la propriété Error est utilisée, mais je ne peux pas trouver qui l’utilise pour créer des rapports sur plusieurs propriétés.

Merci!

public ssortingng this[ssortingng property] { get { ssortingng msg = null; switch (property) { case "LastName": if (ssortingng.IsNullOrEmpty(LastName)) msg = "Need a last name"; break; case "FirstName": if (ssortingng.IsNullOrEmpty(LastName)) msg = "Need a first name"; break; default: throw new ArgumentException( "Unrecognized property: " + property); } return msg; } } public ssortingng Error { get { return null ; } } 

Oui, je vois où vous pourriez utiliser l’indexeur. Ce n’est pas une mauvaise façon de faire, je suppose. J’étais vraiment concentré sur la propriété ‘Erreur’ cependant. J’aime l’idée de contenir les erreurs dans l’object métier. Je pense que ce que je veux faire n’existe pas en natif. Je viens donc de créer un dictionnaire des erreurs (mis à jour chaque fois qu’une propriété change) sur l’object et de laisser l’Erreur renvoyer une liste d’erreurs délimitée par CarriageReturn, comme suit:

  public ssortingng this[ssortingng property] { get { ssortingng msg = null; switch (property) { case "LastName": if (ssortingng.IsNullOrEmpty(LastName)) msg = "Need a last name"; break; case "FirstName": if (ssortingng.IsNullOrEmpty(FirstName)) msg = "Need a first name"; break; default: throw new ArgumentException( "Unrecognized property: " + property); } if (msg != null && !errorCollection.ContainsKey(property)) errorCollection.Add(property, msg); if (msg == null && errorCollection.ContainsKey(property)) errorCollection.Remove(property); return msg; } } public ssortingng Error { get { if(errorCollection.Count == 0) return null; SsortingngBuilder errorList = new SsortingngBuilder(); var errorMessages = errorCollection.Values.GetEnumerator(); while (errorMessages.MoveNext()) errorList.AppendLine(errorMessages.Current); return errorList.ToSsortingng(); } } 

Je pense qu’il est beaucoup plus facile d’utiliser les atsortingbuts de validation.

 class MyBusinessObject { [Required(ErrorMessage="Must enter customer")] public ssortingng Customer { get; set; } [Range(10,99, ErrorMessage="Price must be between 10 and 99")] public decimal Price { get; set; } // I have also created some custom atsortingbutes, eg validate paths [File(FileValidation.IsDirectory, ErrorMessage = "Must enter an importfolder")] public ssortingng ImportFolder { get; set; } public ssortingng this[ssortingng columnName] { return InputValidation.Validate(this, columnName); } public ICollection AllErrors() { return InputValidation.Validate(this); } } 

La classe d’assistance InputValidation ressemble à ceci

 internal static class InputValidation where T : IDataErrorInfo { ///  /// Validate a single column in the source ///  ///  /// Usually called from IErrorDataInfo.this[] /// Instance to validate /// Name of column to validate /// Error messages separated by newline or ssortingng.Empty if no errors public static ssortingng Validate(T source, ssortingng columnName) { KeyValuePair, ValidationAtsortingbute[]> validators; if (mAllValidators.TryGetValue(columnName, out validators)) { var value = validators.Key(source); var errors = validators.Value.Where(v => !v.IsValid(value)).Select(v => v.ErrorMessage ?? "").ToArray(); return ssortingng.Join(Environment.NewLine, errors); } return ssortingng.Empty; } ///  /// Validate all columns in the source ///  /// Instance to validate /// List of all error messages. Empty list if no errors public static ICollection Validate(T source) { List messages = new List(); foreach (var validators in mAllValidators.Values) { var value = validators.Key(source); messages.AddRange(validators.Value.Where(v => !v.IsValid(value)).Select(v => v.ErrorMessage ?? "")); } return messages; } ///  /// Get all validation atsortingbutes on a property ///  ///  ///  private static ValidationAtsortingbute[] GetValidations(PropertyInfo property) { return (ValidationAtsortingbute[])property.GetCustomAtsortingbutes(typeof(ValidationAtsortingbute), true); } ///  /// Create a lambda to receive a property value ///  ///  ///  private static Func CreateValueGetter(PropertyInfo property) { var instance = Expression.Parameter(typeof(T), "i"); var cast = Expression.TypeAs(Expression.Property(instance, property), typeof(object)); return (Func)Expression.Lambda(cast, instance).Comstack(); } private static readonly Dictionary, ValidationAtsortingbute[]>> mAllValidators; static InputValidation() { mAllValidators = new Dictionary, ValidationAtsortingbute[]>>(); foreach (var property in typeof(T).GetProperties()) { var validations = GetValidations(property); if (validations.Length > 0) mAllValidators.Add(property.Name, new KeyValuePair, ValidationAtsortingbute[]>( CreateValueGetter(property), validations)); } } } 

Si je comprends bien, pour utiliser cette interface, vous énumérez les propriétés de l’object et appelez l’indexeur une fois pour chaque propriété. Il incombe à l’appelant d’agréger tous les messages d’erreur.