2011-01-10 31 views
15

Verwenden dieser Methode zum Anzeigen von Modellen in MVC: http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/06/29/how-we-do-mvc-view-models.aspxWie validiere ich DRY?

lässt eine unbeantwortete Frage in meinem Kopf. Es ist also an der Zeit, dass ich es aufgeklärt habe.

Wenn ich Auto Mapper verwenden, um Domäneneigenschaften zu einem dto zuzuordnen, dann schätze ich, dass meine Domain-Ebene eine Reihe von Validierungsregeln zurückgeben kann, wenn der dto einer Domäne Entität zugeordnet ist, die gespeichert wird.

Aber ich sehe keine DRY Möglichkeit, Client-Validierung zu funktionieren und die Fehler zu Modellstatus hinzufügen, damit sie der richtigen Eigenschaft auf dem Ansichtsmodell entsprechen.

Prost

+1

Guter Punkt. Ich habe dies bei meinen letzten Fragen getan, um zu versuchen, dies zu beheben. – nick

Antwort

11

fand ich eine ähnliche Frage mit einigen interessanten Antworten:

Mapping Validation Attributes From Domain Entity to DTO

ich darüber nachgedacht habe, und in gewisser Weise ist es analog zu der Situation haben wir mit serverseitigen und clientseitige Validierung. (z.B. unter Verwendung von sowohl NHibernate Validator als auch jQuery.validate).

Heutzutage ist es ziemlich gut akzeptiert, dass Sie über eine vollständige serverseitige Validierung verfügen sollten. Die clientseitige Validierung ist eine Option, die Sie auswählen können, um Ihre Anwendung benutzerfreundlicher zu gestalten. Früher mussten Sie Ihre clientseitige Validierung manuell implementieren, aber Sie akzeptierten die Doppelarbeit aufgrund des Nutzens der Benutzerfreundlichkeit.

Ich würde argumentieren, dass das, was wir hier behandeln, sehr ähnlich ist. Sie sollten Validierung in Ihrer Domain-Ebene haben. Sie können sich nicht darauf verlassen, dass die konsumierenden Anwendungen die Validierung immer selbst hinzufügen.

Sie haben dann in Ihrer Anwendung die Option, Ihre DTO/View-Modelle mit einer Validierung zu versehen. Sie tun dies, weil es hilfreicher ist, Validierungsfehler in der Ansicht zu behandeln, anstatt sie an die Domäne weiterleiten zu lassen, die eine Ausnahme auslösen oder eine weniger hilfreiche Fehlermeldung ausgeben könnte. Der Punkt ist, dass Sie sich aus der Domänenperspektive nicht darauf verlassen, dass dies getan wird. Sie sind immer noch zuversichtlich in Ihr System, weil Sie wissen, wenn irgendwelche schlechten Daten durchkommen, wird Ihr Modell es fangen.

Der Client/Server-Fall ist ein Problem in diesen Tagen, weil so viel Arbeit getan wurde, um es zu automatisieren, den clientseitigen Code aus dem serverseitigen Code (z. B. ModelValidatorProvider in ASP.Net MVC) generiert. Ich glaube, dass, wenn immer mehr Menschen die Verwendung von Ansichtsmodellen/DTOs aufgreifen, wir ähnliche Lösungen für die automatische Zuordnung der Domänenvalidierung zu den DTOs sehen werden (it's already happening with AutoMapper).

Also kurz gesagt, meine (eher pragmatisch als ideal;)) Antwort lautet:

Akzeptieren Sie die Verletzung von DRY für jetzt tun Validierung in beiden Orten, und versuchen, Projekte beizutragen, die es automatisieren wollen in Zukunft

+0

Ich gebe dies als Antwort, weil Sie die Kompromisse sehr gut hervorheben und darauf hinweisen, dass es keine universell perfekte Lösung gibt. – nick

2

Ein gemeinsamer Ansatz ist es, alle Validierung Ihrer Ansicht Modelle zu setzen, in der Regel von Daten Anmerkungen verwenden. Mit MVC können Sie automatisch eine clientseitige Validierung (JavaScript) aus den Datenanmerkungen generieren. Ziemlich trocken.

Ihre Controller-Post-Aktionen übernehmen das View-Modell und überprüfen die IsValid-Eigenschaft. Auf diese Weise werden die Validierung Sie auf Client und Server mit dem gleichen Code (oder sollte, sage ich Attribute im Fall von Daten Anmerkungen):

[HttpPost] 
public ActionResult ResetPassword(ResetPasswordViewModel viewModel) 
{ 
    if (ModelState.IsValid) 
    { 
    // convert to dto/entity and pass to next layer 
    // redirect to success page 
    return RedirectToAction("ResetPasswordSuccess"); 
    } 
    // display original view which will display error messages 
    return View(); 
} 

nur hinzufügen, dass nur durch die Controller-Aktion nimmt in der mit viewModel als Parameter überprüft das Standard-MVC-Modellbinder automatisch Ihr Ansichtsmodell und fügt der ModelState-Fehlerauflistung, die zum Anzeigen von Fehlern in Ihren Ansichten verwendet wird, Fehler hinzu.

+2

Für mich ist das entweder nicht trocken, weil ich am Modell und der VM validieren muss - oder es erlaubt mir nicht, meine Geschäftsregeln am Modell durchzusetzen, weil ich der VM nur eine Validierung hinzufüge. – nick

+0

Ich schätze, Sie sagen im Grunde, dass Sie die Entscheidung getroffen haben, dass Ihre Domain immer nur von Ihrer Web-App konsumiert wird und dass Entwickler Ihrer Web-App immer View-Modelle anstelle von Domain-Entitäten verwenden sollten, um CRUD-Aktionen durchzuführen? –

+0

d. H. Sie akzeptieren, dass das Domänenmodell auf fehlerhafte Daten beschränkt ist, weil Sie wissen, dass Ihre Entwickler es nicht auf diese Weise verwenden werden? –

5

Ich bevorzuge es, das Modell als eine Eigenschaft auf dem ViewModel zusammen mit anderen anzeigen spezifischen Feldern. Auf diese Weise wird es von MVC beim Binden validiert und ich kann es auf dem Backend validieren, wenn es nicht über MVC gebunden ist. Auf diese Weise wird die Client-Validierung von MVC bereitgestellt und ich bekomme saubere Modelle mit Validierungsobjekt, die nicht direkt mit einer Ansicht verknüpft sind.

public class MyViewModel 
{ 
    public MyModel MyModel {get;set;} 
    public bool IsSomethingAllowed {get;set;} 
} 

public class MyModel 
{ 
    public int Id {get;set;} 
    [Required] 
    public string Name {get;set;} 
} 
+1

Dies ist eine Konvention, die mein Team beschlossen hat. Bei den Projekten, an denen wir arbeiten, ist der Verlust der DRY-Validierung für lose gekoppelte Ansichtsmodelle keinen Kompromiss wert - sie ist weniger effizient und fehleranfälliger. – nick

+1

Es gibt Probleme bei der Verwendung von Domänenentitäten. z.B. (1) Was ist, wenn der Typ inkorrekt ist, z. keine gültige Ganzzahl? Jede Validierung, die Sie für Ihre Domain-Entität haben, wird nicht einmal getroffen, die Model-Bindung schlägt fehl und Sie erhalten eine generische Nachricht. Bei Ansichtsmodellen können Sie die Zeichenfolge für alle Eigenschaften verwenden, um sicherzustellen, dass die Modellbindung funktioniert, und dann kann die Validierung des Ansichtsmodells erkennen, ob es sich um eine gültige Ganzzahl handelt, und dem Benutzer eine benutzerdefinierte Fehlermeldung anzeigen. (2) Wenn Sie Ressourcendateien für Validierungsnachrichten verwenden, müssen Ihre Domänenobjekte auf Ihre Ressourcendatei-DLL verweisen. Nicht sehr nett! –

+0

Nicht sehr nett, stimme ich zu. Möchten Sie jedoch Geschäftsregeln in der Modellschicht durchsetzen oder nicht? Dies scheint der wichtigste Kompromiss zu sein. Gut, dass Sie das aber aufzeigen. – nick