2010-11-30 1 views
15

Ich möchte Validator.TryValidateValue() verwenden, aber verstehe nicht die Mechanik. Sagen Sie, ich habe folgendes:Verstehen ValidationContext in DataAnnotations

public class User { 
    [Required(AllowEmptyStrings = false)] 
    [StringLength(6)] 
    public string Name { get; set; } 
} 

und die Methode:

public void CreateUser(string name) {...} 

Meine Validierungscode ist:

ValidationAttribute[] attrs = bit of reflection here to populate from User class 
var ctx = new ValidationContext(name, null, null); 
var errors = new List<ValidationResult>(); 
bool valid = Validator.TryValidateValue(name, ctx, errors, attrs); 

Es funktioniert gut, bis der Wert von namenull ist. Ich bekomme ArgumentNullException bei der Instanziierung ValidationContext und verstehe nicht warum. TryValidateValue() erfordert auch Nicht-Null-Kontext. Ich habe einen Wert und eine Liste von Attributen, gegen die ich validieren kann. Was ist das für ValidationContext?

+0

Ich habe mich damit nicht getäuscht, bevor es für mich aussieht, dass Sie den Objekttyp in den ValidationContext übergeben sollten, nicht die Eigenschaft ... also eine Instanz von User übergeben, die nicht null ist. –

+0

Wenn Sie das Attribut von DataAnnotation anpassen möchten, können Sie zu [mein Beitrag] gehen (http://weblogs.asp.net/thangchung/archive/2010/06/25/extearning-resource-provider-for-soring- resources-in-the-database.aspx) Außerdem passen Sie den Validator an. – thangchung

Antwort

18

Das einzige, was an Ihrem Code falsch ist, ist das Instanzobjekt für Ihren Validierungskontext. Die Instanz muss nicht der Wert sein, der validiert wird. Für Validator.ValidateProperty muss das Objekt, das die Eigenschaft besitzt, ja sein, aber für Validator.ValidateValue ist "this" ausreichend.

Ich schrieb eine Validierung Helper-Klasse, um das Setup zu tun; Dadurch kann ich beliebige Werte von überall eingeben.

public class ValidationHelper 
{ 
    private List<ValidationResult> m_validationResults = new List<ValidationResult>(); 
    private List<ValidationAttribute> m_validationAttributes = new List<ValidationAttribute>(); 

    public Tuple<bool, List<string>> ValidateDOB(DateTime? dob) 
    { 
     m_validationAttributes.Add(new CustomValidationAttribute(typeof(DateOfBirthValidator), "ValidateDateOfBirth")); 
     bool result = Validator.TryValidateValue(dob, 
          new ValidationContext(this, null, null), 
          m_validationResults, 
          m_validationAttributes); 
     if (result) 
     { 
      return Tuple.Create(true, new List<string>()); 
     } 
     List<string> errors = m_validationResults.Select(vr => vr.ErrorMessage).ToList(); 
     return Tuple.Create(false, errors); 
    } 
} 

Wenn Sie Eigenschaften validieren, die die Validierung haben auf dem Grundstück Attribute, dann ist es viel einfacher:

internal void Validate(T value) 
{ 
    if (!m_Initializing && TrackChanges && !Entity.IsImmutable) 
    { 
     Validator.ValidateProperty(value, new ValidationContext(Entity, null, null) { MemberName = PropertyName ?? ModelName }); 
    } 
} 

„Entity“ eine Eigenschaft der aktuellen Klasse ist, die das Objekt verweist, das ich will bestätigen. Dadurch kann ich Eigenschaften anderer Objekte überprüfen. Wenn Sie bereits im Objekt sind, wird "das" wieder ausreichen.

+1

Danke, mein Kollege schlug mir vor, dass ich ValidationContext alles andere als null übergeben sollte, und es funktionierte. Aber ich verstehe immer noch nicht, warum TryValidateValue() ValidationContext verlangt. Schlechtes Design? Nur die Schöpfer wissen, aber ich hoffe nicht, ihre Antwort hier so +50 zu Ihnen zu sehen. – UserControl

+3

Danke! Die Objektinstanz ist zum Validieren von Objekten und Eigenschaften, aber viel weniger zum Validieren von Werten geeignet, und in allen Fällen ist es dieselbe ValidationContext-Klasse. Sie erhalten möglicherweise einen Einblick in die Designerabsicht, indem Sie den Quellcode im Visual Studio-Debugger schrittweise durchlaufen. Anweisungen zum Herunterladen der Quelle und zum Einrichten von Visual Studio zum Debuggen in .NET Framework-Klassen finden Sie unter http://referencesource.microsoft.com/. –

+3

@UserControl Hier ist ein Blogbeitrag, der ValidationContext von einem der Autoren erläutert: http://jeffhandley.com/archive/2010/10/25/RiaServicesValidationContext.aspx – Michael