2016-03-25 5 views
4

Ich habe eine Ansicht, die mehrere Modelle benötigt, um korrekt zu funktionieren. Also habe ich ein Modell erstellt, das eine Sammlung von mehreren (Teil-) Modellen ist. Dies ist das Modell.Validierung des Formulars, wenn das Modell eine Sammlung von Untermodellen ist

public class PolicyDetail 
{ 
    public Policy Policy { get; set; } 
    public IEnumerable<Insured> Insureds { get; set; } 
    public IEnumerable<Risk> Risks { get; set; } 
    public IEnumerable<Construction> Constructions { get; set; } 
} 

Und hier ist ein Beispiel dafür, was eines der Teilmodelle aussehen, die aus der Datenbank eine tatsächliche Einheit ist:

public class Policy 
{ 
    [Key] 
    public int PolicyID { get; set; } 

    [DisplayName("Policy Number")] 
    public Guid PolicyNumber { get; set; } 

    [Required(ErrorMessage = "Please enter a valid Effective Date.")] 
    [DataType(DataType.DateTime)] 
    [DisplayName("Effective Date")] 
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)] 
    public DateTime EffDate { get; set; } 

    [Required(ErrorMessage = "Please enter a valid Expiration Date.")] 
    [DataType(DataType.DateTime)] 
    [DisplayName("Expiration Date")] 
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)] 
    public DateTime ExpDate { get; set; } 

    public Boolean IsActive { get; set; } 
} 

Das war alles gut funktioniert, bis, bis ich versuchte einreichen ein Formular mit Fehlern, um die Validierung zu testen. Ich hätte das vielleicht sehen sollen (vielleicht?), Aber weil das aktuelle Modell keine Validierungs-Tags hat, übergibt es immer die Prüfung if (ModelState.IsValid). Gibt es eine Möglichkeit, alle Datenanmerkungen aus den Unterklassen zu erzwingen oder zu erben?

Oder mache ich das alles falsch, mit einem Modell, das eine Sammlung von anderen Modellen ist? Die Sache ist, ich möchte in der Lage sein, mehrere db-Entities aus derselben Ansicht zu bearbeiten/hinzufügen.

EDIT:

This article von Josh Carroll sieht genau das, was ich brauche. Aber wenn ich es implementiere, bekomme ich einen Null-Objekt-Fehler. Hier ist, was ich tue:

public class PolicyDetail 
{ 
    [Required, ValidateObject] 
    public Policy Policy { get; set; } 
    public IEnumerable<Insured> Insureds { get; set; } 
    public IEnumerable<Risk> Risks { get; set; } 
    public IEnumerable<Construction> Constructions { get; set; } 
} 

Dann in der Überschreibung Methode, die er bietet:

protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
    { 
     var results = new List<ValidationResult>(); 
     var context = new ValidationContext(value, null, null); 

     Validator.TryValidateObject(value, context, results, true); 

     if (results.Count != 0) 
     { 
      var compositeResults = new CompositeValidationResult(String.Format("Validation for {0} failed!", validationContext.DisplayName)); 
      results.ForEach(compositeResults.AddResult); 

      return compositeResults; 
     } 

     return ValidationResult.Success; 
    } 
} 

die Parameter "Wert" in Null kommt, so dass es Fehler auf dieser Linie:

Validator.TryValidateObject(value, context, results, true); 

Fehle ich etwas? Etwas falsch machen?

+0

Mögliches Duplikat von: http://stackoverflow.com/questions/7663501/dataannotations-recursively-validating-an- entire-object-graph –

+0

Überprüfung dieses Threads. Danke –

+0

Nur als eine Alternative: Ich empfehle, [FluentValidation] (https://github.com/JeremySkinner/FluentValidation) für die nicht-grundlegenden Validierungsfälle zu betrachten, zum Beispiel könntest du [FluentValidation - Validierung eines View-Modells das enthält eine Liste eines Objekts] (http://stackoverflow.com/a/21310109/4805174) für Ideen. – kayess

Antwort

1

Sie können manuell die Validierungen auf den Unter Modelle nennen dies mit: https://msdn.microsoft.com/en-us/library/dd411772.aspx

var context = new ValidationContext(model.Policy, serviceProvider: null, items: null); 
var validationResults = new List<ValidationResult>(); 

bool isValid = Validator.TryValidateObject(model.Policy, context, validationResults, true); 

Sie können dann die ModelState.AddModelError verwenden, um die Antwort von dem zu bauen.

Definitiv nicht die eleganteste mögliche Lösung, aber vielleicht einfacher als das Umschreiben, was Sie haben.