2016-04-19 12 views
0

Ich habe eine Frage bezüglich der Property-Validierung, jedoch konnte ich noch keine passende Antwort finden.Validierungseigenschaft, basierend auf einer anderen Modelleigenschaft

Ich habe die folgenden Klassen

public class IndexViewModel 
{ 
    public Film Film { get; set; } 

    public ReviewModel Review { get; set; } 
} 

public class ReviewModel 
{ 
    [RequiredIf // only fire if 'Genre' is equal to Genre.Horror] 
    public string Text { get; set; } 
} 

public class Film 
{ 
    public string Title { get; set; } 
    public Director Director { get; set; } 
    public Genre Genre { get; set; } 
} 

public class Director 
{ 
    public string Name { get; set; } 
} 

public enum Genre 
{ 
    Horror, 
    Thriller, 
    SciFi, 
    Drama 
} 

Ist es möglich, ein [RequiredIf] Attribut auf der Text Eigenschaft in ReviewModel die Validierung basierend auf dem Wert von Genre im Film Modell feuert hinzuzufügen. Jede Hilfe würde sehr geschätzt werden.

+0

Überprüfen Sie die Foolproof-Validierung: https://foolproof.codeplex.com/ und FluentValidation: https://github.com/JeremySkinner/FluentValidation – solidau

+0

Nein, es ist nicht möglich, Validierungsattribute zu verwenden, da der Validierungskontext für das 'ReviewModel 'gilt 'nur. Aber Ihr 'IndexViewModel' ist nicht die korrekte Verwendung eines Ansichtsmodells. Es sollte die Eigenschaften enthalten, die Sie als flache Struktur bearbeiten müssen, und sollte keine Eigenschaften enthalten, die Datenmodelle sind. –

Antwort

2

Ich würde die Verwendung von Validierungsattributen nicht empfehlen, wenn die Eigenschaften, die validiert werden müssen, nicht in der Klasse enthalten sind, der sie zugeordnet ist. Ich habe keine RequiredIfAttribute Implementierung gesehen, die solche Modelle durchschneidet. (Here's a good one from a different question.)

Was ist mit einer einfachen Implementierung von IValidatableObject? Es wäre ziemlich klar, und MVC wird darauf achten, wenn das Modell gebaut wird.

public class IndexViewModel : IValidatableObject 
{ 
    public Film Film { get; set; } 

    public ReviewModel Review { get; set; } 

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) 
    { 
     if (Film.Genre == Genre.Horror && string.IsNullOrWhiteSpace(Review.Text)) 
     { 
      yield return new ValidationResult(
       "Please provide a review for this film.", 
       new string[] { nameof(Review.Text) }); 
     } 
    } 
} 
0

Legen Sie es in Ihrem Business-Schicht.

[RequiredIf // only fire if 'Genre' is equal to Genre.Horror 

]

, wenn Sie es auf Ihrem Modell setzen müssen, könnte man genauso gut implementieren

System.ComponentModel.IValidatableObject 

und dann den ObjectValidator verwendet es zu validieren.

Aber basierend auf der Erfahrung, ich grundlegende Attributdekoration auf meinem Modell wie Required und StringLength, so dass asp.net MVC kann aufgreifen, und dumpen die wichtige Geschäftsregel in meinem Service-Layer, da die Validierungslogik ist selten so einfach und erfordern normalerweise externe Datenelemente wie zusätzliche Aufrufe an die Datenbank.

es hängt wirklich von Ihren Anwendungsfällen ab. Ich möchte meine Datenklassen dumm halten, weil ich erwarte, dass die Daten verschoben werden und somit die Validierungslogik während der Serialisierung verloren geht, d. H. JSON-Serialisierung.

Verwandte Themen