2010-12-07 3 views
11

Wie bleibe ich DRY mit asp.net mvc Ansicht Modelle & Daten Annotation (Validierung, Anzeige und Datenmodellierung) Attribute mit Asp.Net MVC? Ich habe sowohl Modellobjekte als auch aktionsspezifische Ansichtsmodelle an Ansichten übergeben. Ich finde beide Richtungen, um einige Probleme mit dem Versuch zu haben, DRY zu bleiben.Wie bleibe ich DRY mit asp.net mvc View-Modelle und Daten Annotation-Attribute?

  • Verwenden Modellobjekte als View-Modell: Diese in einfachen Situationen funktioniert gut und ermöglicht es Ihnen, nur die Daten Anmerkung schreiben Attribute einmal für jedes Modellobjekt. Das Problem tritt auf, wenn Sie komplexe Ansichten haben, die mehr als einen Objekttyp erfordern. Die resultierende Ansichtsmodellarchitektur ist ein Mischmasch der Verwendung von Ansichtsmodellklassen und tatsächlichen Modellklassen. Darüber hinaus kann diese Methode Modelleigenschaften für Ihre Ansicht verfügbar machen, die Sie nicht beabsichtigen.

  • Verwenden Sie eine eindeutige View-Modellklasse pro Aktion: Die View-Modellklasse enthält nur bestimmte Ansichtseigenschaften, die mit Datenanmerkungsattributen versehen sind. Meiner Erfahrung nach erwies sich diese Methode nicht als sehr TROCKEN, da Datenanmerkungsattribute dazu neigen, über Ansichtsmodellklassen hinweg zu duplizieren. Zum Beispiel teilen sich die Ansichtsmodelle "Neu" und "Bearbeiten" eine Menge, aber nicht alle Eigenschaften und Datenanmerkungen.

Wie kann ich & Datenaufbelichtung Attribute mit asp.net MVC Ansicht Modelle trocken bleiben?

+0

Leider gibt es keine perfekte Lösung, die nicht zu einer * Verdoppelung der Validierungsmetadaten führt.Zumindest keine, die ich gefunden habe. –

Antwort

0

Bisher habe ich festgestellt, dass Vererbung Eigenschaften kombinieren Shared am besten funktioniert. Ich verwende eine eindeutige Ansichtsklasse pro Aktion und bin mit der bisherigen Lösung sehr zufrieden. Es löst nicht 100% der Fälle, aber es deckt die Mehrheit ab und eliminiert fast doppelte Datenvertragsattribute.

2

Ich habe Metadaten definiert in C# wie folgt aus:

public class Meta 
{ 
    public class Client 
    { 
     public class Name 
     { 
      public const bool Required = true; 
      public const DataType Type = DataType.Text; 
      public const int MaxLength = 30; 
      public const int MinLength = 1; 
      public const string Regex = @"^[\w\d\.-_]{1,30}$"; 
     } 

     public class Email 
     { 
      public const bool Required = false; 
      public const DataType Type = DataType.EmailAddress; 
      public const int MaxLength = 256; 
      public const int MinLength = 4; 
      public const string Regex = @"^[email protected]+$"; 
     } 
    } 
} 

erklärt sie als Konstanten können Sie DataAnnotations auf beiden BL Entitäten und UI-Modelle verwenden:

[DataContract] 
[Serializable] 
public class ClientInfo 
{ 
    [DataMember] 
    [Required(AllowEmptyStrings = !Meta.Client.Name.Required)] 
    [StringLength(Meta.Client.Name.MaxLength, MinimumLength = Meta.Client.Name.MinLength)] 
    [RegularExpression(Meta.Client.Name.Regex)] 
    public string Name { get; set; } 

    ... 
} 

gut, ja, Sie duplizieren die Attribute, aber keine Metadaten!

create table dbo.Client ( -Name nvarchar ({# Client.Name.MaxLength}) {: In addtition i SQL-Skripte aus einer Vorlage (spezielle Verarbeitung für * .Required, usw.) eine triviale Präprozessor haben zu generieren # Client.Name.Required}, Email nvarchar ({# Client.Email.MaxLength}) {# Client.Email.Required}, ....

auf UI können Sie die Vererbung verwenden, um nicht Eigenschaften zu duplizieren Wenn Sie zum Beispiel ein Modell mit 10 Eigenschaften haben, aber nur 2 davon bearbeiten müssen, erstellen Sie EditModel und erben ViewModel von diesem. Der Schlüssel hier ist, Metadaten in einem einzigen Speicher zu haben und so viel wie möglich zu verwenden Sie erhalten die Idee.

4

Eine gute Option wäre, von DataAnnotations zu Fluent Validation zu wechseln. Es ermöglicht Ihnen, allgemeine Validierungslogik in einer Klasse zu kapseln, die Sie später auf Ihre Modelle anwenden können.

Vom documentation:

[Validator(typeof(PersonValidator))] 
public class Person { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Email { get; set; } 
    public int Age { get; set; } 
} 

public class PersonValidator : AbstractValidator<Person> { 
    public PersonValidator() { 
     RuleFor(x => x.Id).NotNull(); 
     RuleFor(x => x.Name).Length(0, 10); 
     RuleFor(x => x.Email).EmailAddress(); 
     RuleFor(x => x.Age).InclusiveBetween(18, 60); 
    } 
} 
+2

Das sieht definitiv nach einer attraktiven Option aus, hilft aber bei dieser speziellen Frage nicht wirklich. Es sei denn, ich vermisse etwas –

+0

Die Antwort zielt darauf ab, eine Gruppe von Validatoren in einer Klasse zu gruppieren, die Sie dann auf verschiedene ViewModels anwenden können. Beispielsweise können Sie eine Klasse mit den allgemeinen Validatoren für die neuen und Edit ViewModels deklarieren, Wenn Sie ViewModels verwenden, ist es unvermeidlich, einige Duplikate zu haben, aber ich denke, es ist ein guter Kompromiss, hauptsächlich aufgrund der Gründe geben. Sie könnten die erste Antwort mit diesem ergänzen. – CGK