Sollte die Ansicht keine Validierung durchführen?

10

Ich habe " In MVC sollte ein Modell die Validierung verarbeiten? " Gelesen, weil ich neugierig war, wohin die Validierungslogik auf einer MVC-Website gehen soll. Eine Zeile in der oberen Antwort lautet wie folgt: "Controller sollten die Validierung übernehmen, Modelle sollten die Verifizierung übernehmen."

Das hat mir gefallen, aber ich habe mich gefragt, warum wir aus mehreren Gründen keine Datenüberprüfung in der Ansicht durchführen würden:

  1. Ansichten bieten normalerweise eine robuste Validierungsunterstützung (JS-Bibliotheken, HTML5-Tags).
  2. Ansichten können lokal validiert werden, wodurch Netzwerk-E / A reduziert werden
  3. Die Benutzeroberfläche wurde bereits unter Berücksichtigung des Datentyps (Kalender für Daten, Spinner für Zahlen) entwickelt, sodass sie nur einen kleinen Schritt von der Validierung entfernt ist

Die Validierung an mehr als einem Ort widerspricht dem Konzept von MVC, Verantwortlichkeiten zu isolieren. Daher erscheint es unangemessen, dies in beiden Fällen zu tun. Ist die Datenvalidierung nur im Controller wirklich der dominierende Ansatz?

WannabeCoder
quelle
Das Problem hier könnte eine falsche Zweiteilung sein: Es gibt keinen Grund, warum Sie nicht an mehreren Stellen eine Validierung durchführen können, und wenn Sie sich die Situation als "entweder-oder-nicht-beides" vorstellen, kann dies Ihre Sicht (Wortspiel!) Auf diese Frage trüben . Eine Art clientseitige Validierung auf einer Website kann beispielsweise sehr nützlich sein, da Benutzer sofortiges Feedback erhalten, diese jedoch nicht vertrauenswürdig ist und daher nicht die einzige Validierung sein kann.
Miles Rout

Antworten:

10

Ich glaube nicht, dass es einen einzigen Ort gibt, an dem man sagen kann, dass die gesamte Validierung stattfinden sollte. Dies liegt daran, dass auf einer standardmäßigen asp.net mvc-Website einige verschiedene konkurrierende Programmierstrategien zusammenarbeiten.

Erstens haben wir die Idee, die Domänenlogik in Modelle, die Aktionslogik in Controller und die Anzeige in eine Ansicht zu unterteilen. Dies basiert auf der Idee, dass die gesamte Logik auf dem Server stattfindet, wobei der Browser lediglich ein Rendering der Ansicht bereitstellt.

Anschließend erweitern wir die Ansicht mithilfe von clientseitigem Javascript. Dies ist heutzutage so weit fortgeschritten, dass die Idee einer "einseitigen Website" mit Jquery / Knockout / Angular gängige Praxis ist.

Diese Vorgehensweise kann dem Schreiben einer gesamten clientseitigen Anwendung entsprechen, die selbst ein MVC- oder MVVM-Muster implementiert. Wir verunglimpfen die Ansicht auf ein Datenübertragungsobjekt und den Controller auf einen Service-Endpunkt. Verschieben der gesamten Geschäfts- und Benutzeroberflächenlogik in den Client.

Dies kann zu einer besseren Benutzererfahrung führen, aber Sie müssen einem im Wesentlichen nicht vertrauenswürdigen Kunden vertrauen. Sie müssen also weiterhin eine Validierungslogik auf dem Server ausführen, unabhängig davon, wie gut Ihr Client seine Anforderungen vorab validiert.

Außerdem haben wir häufig Validierungsanforderungen, die vom Kunden nicht ausgeführt werden können. z.B. "Ist meine neue ID einzigartig?"

Jede Anwendung, die Sie mit dem Ziel erstellen, die beste Erfahrung / Leistung zu erzielen, leiht sich notwendigerweise mehrere Programmierparadigmen aus und macht Kompromisse, um ihr Ziel zu erreichen.

Ewan
quelle
4
+1 und um zu betonen: Vertraue niemals den vom Kunden geposteten Daten. Je.
Machado
Wie ich das gelesen habe: "Validierung ist kein isoliertes Konzept - alle Teile Ihrer Anwendung müssen in unterschiedlichen Kontexten gegeneinander validiert werden." Sinnvoll, auch wenn mehr Arbeit.
WannabeCoder
ja, aber auch: "Sie können zwei (oder mehr) Apps haben, die alle unterschiedlichen Mustern folgen"
Ewan
" den · i · grate : Unglaublich kritisieren, herabsetzen. " Ich glaube nicht, dass Sie dieses Wort richtig verwenden. Ansonsten aber gute Antwort.
Kdbanman
Nein, das habe ich gemeint
Ewan
1

Die Validierung an mehr als einem Ort widerspricht dem Konzept von MVC, Verantwortlichkeiten zu isolieren. Daher erscheint es unangemessen, dies in beiden Fällen zu tun.

Könnten hier mehrere Validierungsverantwortlichkeiten berücksichtigt werden? Wie Sie in Ihrer # 3 gesagt haben:

Die Benutzeroberfläche wurde bereits unter Berücksichtigung des Datentyps (Kalender für Daten, Spinner für Zahlen) entwickelt, sodass sie nur einen kleinen Schritt von der Validierung entfernt ist

Also vielleicht ist es:

Ansicht : Überprüfen Sie Eingabetyp, Format, Anforderung ... Grundlegende Validierung von Benutzereingaben, die nichts mit der Geschäftslogik zu tun hat. Fangen Sie all diese flauschigen Dinge ab, bevor wir Netzwerkverkehr generieren, indem Sie eine Anfrage an den Server stellen.

Modell : Überprüfen Sie die geschäftlichen Belange der Daten. Ist das ein rechtlicher Wert gemäß den Geschäftsregeln? Ja, es ist ein numerischer Wert (das haben wir in der Ansicht sichergestellt), aber macht es Sinn?

Nur ein Gedanke.

Roter Mann
quelle
1

Ich gehe davon aus, dass Sie eine Validierung für die Persistenz benötigen.

Nicht nur Ansicht, sondern auch Modell sollte auch nicht validiert werden. Während meiner IT-Tage wurde mir klar, dass DDD eine der Möglichkeiten ist, um sicherzustellen, dass Sie die Dinge tatsächlich richtig machen, d. H. Klassen sind tatsächlich dafür verantwortlich, was sie sein sollten.

Wenn Sie dem domänengesteuerten Design folgen, enthalten Ihre Modelle Ihre Geschäftslogik, und das ist es. Aber sie beinhalten keine Validierung, warum nicht?

Nehmen wir an, Sie sind bereits so weit, wie Sie verwenden, Data Mapperanstatt Active RecordIhre Domain-Schicht beizubehalten. Sie möchten jedoch, dass Modelle validiert werden, und fügen die Validierung Ihrem Modell hinzu.

interface Validation
{
    public function validate();
}

class ConcreteModel extends MyModel implements Validation
{
    public function validate() { // the validation logic goes here }
}

Die Validierungslogik stellt sicher, dass Sie das Modell korrekt in Ihre MySQL-Datenbank einfügen können ... Nach einigen Monaten möchten Sie Ihre Modelle auch in noSQL-Datenbanken speichern, in denen andere Validierungsregeln als in MySQL erforderlich sind.

Sie haben jedoch ein Problem, Sie haben nur eine Validierungsmethode, müssen diese jedoch auf Modelzwei verschiedene Arten validieren .

Die Modelle sollten das tun, wofür sie verantwortlich sind , sie sollten sich um Ihre Geschäftslogik kümmern und es gut machen. Die Validierung ist an die Persistenz gebunden, nicht an die Geschäftslogik. Daher gehört die Validierung nicht zu einem Modell .

Sie sollten Validatorstattdessen s erstellen , das ein Modell zur Validierung in seinem Konstruktor als Parameter verwendet, die ValidationSchnittstelle implementiert und diese Validators zur Validierung Ihrer Objekte verwendet.

interface Validation
{
    public function validate();
}

class MySQLConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model here
    }
}

class RedisConcreteModelValidator implements Validation
{
    public function __construct(ConcreteModel $model) { }

    public function validate()
    {
        // you validate your model with different set of rules here
    }
}

Wenn Sie zu einem späteren Zeitpunkt entscheiden, dass Sie eine weitere Validierungsmethode für eine andere Persistenzschicht hinzufügen möchten (weil Sie entschieden haben, dass Redis und MySQL nicht mehr der richtige Weg sind), erstellen Sie einfach eine andere Validatorund verwenden Ihren IoCContainer, um die richtige Instanz zu erhalten auf deine config.

Andy
quelle
1

Für viele Entwickler sind Fat-Modelle gegen dumme hässliche Controller die bevorzugte Methode.

Grundkonzept im Text ist

... Denken Sie also immer daran, dass das Modell nicht nur die Datenbank ist. Sogar die Daten, die Sie von Webdiensten erhalten, können als Modell ausgedrückt werden! Ja, sogar Atom-Feeds! Frameworks, die die Einführung in das Modell erschüttern, erklären dies fast nie im Voraus, was Missverständnisse nur verschlimmert.

und

Die Ansicht sollte sich nur mit dem Generieren und Präsentieren einer Benutzeroberfläche befassen, damit Benutzer dem Modell Absichten mitteilen können . Controller sind die Orchestratoren, die UI-Eingaben in Aktionen auf dem Modell übersetzen und Ausgaben von jeder Ansicht zurückgeben, die auf die präsentierten Modelle aufmerksam gemacht wurde. Controller müssen das Anwendungsverhalten nur in dem Sinne definieren, dass sie Benutzereingaben auf Aufrufe in Modellen abbilden. Über diese Rolle hinaus sollte jedoch klar sein, dass alle anderen Anwendungslogiken im Modell enthalten sind. Controller sind bescheidene Kreaturen mit minimalem Code, die nur die Bühne bereiten und die Dinge auf organisierte Weise arbeiten lassen.

Die Ansicht sollte sich nur mit dem Generieren und Präsentieren einer Benutzeroberfläche befassen, damit Benutzer die Absicht mit dem Modell kommunizieren können. Dies ist der wichtige Teil. Ein Modell sollte die gespeicherten Daten definieren, daher muss es auch für die Überprüfung der Gültigkeit der Daten verantwortlich sein.

Bei der Aufnahme einer Person muss jede Person eine vom Land angegebene eindeutige ID-Nummer haben. Diese Überprüfung erfolgt (im Allgemeinen) durch die UNIQUESchlüsselprüfung durch die Datenbank. Jede gegebene ID-Nummer sollte einige Kontrollschritte erfüllen (die Summe der ungeraden Ziffern sollte gleich der Summe der geraden Ziffern usw. sein). Diese Art von Kontrollen sollte von der durchgeführt werdenModel

Der Controller sammelt Daten von Modelund leitet sie an Viewdie Benutzerdaten weiter oder leitet sie an diese weiter und leitet Viewsie weiter Model. Eine Einschränkung des Zugriffs auf die Daten und ihrer Validierung sollte nicht von der Controller. Es war Controllerderjenige, der die Cookie-Daten sammelt und Modelder prüft, ob es sich um eine gültige Sitzung handelt oder ob der Benutzer Zugriff auf diesen Teil der Anwendung hat.

Viewist die Benutzeroberfläche, die Daten vom Benutzer sammelt oder dem Benutzer präsentiert. Einfache Überprüfungen können durchgeführt werden, indem der ViewBenutzer die E-Mail-Adresse eingibt oder nicht (dies kann auch in der Ansicht erfolgen). IMO.

View ist die Clientseite, und Sie sollten die Benutzereingaben nicht verschieben. Javascripts können möglicherweise nicht auf der Clientseite ausgeführt werden. Ein Benutzer kann handschriftliche Skripte verwenden, um sie zu ändern oder das Skript mithilfe des Browsers zu deaktivieren. Sie können clientseitige Validierungsskripte festlegen, aber niemals sollten Sie sie verschieben und die Ebene wirklich überprüfen Model.

Gefallener Engel
quelle
Nur um zu betonen, dass die Ansicht, die sich nur mit der Benutzeroberfläche befasst, nicht bedeutet, dass sie keine Validierung durchführen kann. Die sofortige Rückmeldung an Benutzer, wenn sie einen Fehler machen, ist in der Tat ein wirklich wichtiger Teil der Gründe, warum clientseitiges Scripting ist nützlich im Zusammenhang mit MVC auf Websites angewendet.
Miles Rout
@ MilesRout in der Tat meine ich, dass mit Simple checks can be done by the View like the user input e-mail address or not vielleicht ist es nicht so klar. Aber was Sie gesagt haben, gilt auch für mich. Einfache und einfache Überprüfungen können in der Ansicht problemlos durchgeführt werden.
FallenAngel
Ich war nicht anderer Meinung als du.
Miles Rout
0

Ansichten sollten Validierungen für ff-Zwecke durchführen:

  1. ) Eine Front-End-Validierung kann den Datenverkehr auf Ihrem Server reduzieren.
  2. ) Es verarbeitet ungültige Daten, bevor sie auf Ihrem Server übertragen werden können.
  3. ) Wenn Sie eine höhere Sicherheit wünschen, ist eine Kombination aus Front-End- und Back-End-Validierung besser.
Azurblau
quelle