2010-01-16 5 views
6

Ich sehe, dass asp.net mvc 2 hat stark typisiert geholfen und zunächst auf die Art, wie es funktioniert Ich denke, vielleicht mache ich etwas falsch in asp.net MVC 1 in Bezug auf die Datenbindung, um die Ansicht zu machen und wieder auf die Regler.asp.net mvc stark typisierte Helfer - sollte Ihr Render-Binding-Objekt dasselbe sein wie Ihr Buchungsobjekt?

Ich habe oft verschiedene Objekte zum Rendern der Ansicht und zum Zurücksetzen auf den Controller. ist das falsch ?? Es scheint natürlich, dass Sie beim Rendern der Ansicht oft ein Viewmodel haben, das Listen für Dropdowns usw. enthält, aber für Ihr Posting möchten Sie nur die Eigenschaften, die für das Zurückschreiben benötigt werden.

zum Beispiel auf dem Weg in für Rendering, meine Viewmodel wie diese aussehen könnten

public class PersonViewModel 
{ 
     public int Age; 
     public string FIrst; 
     public JobCategory[] JobCategories; 
     public Sport[] Sports; 
     public int NumberOfChildren; 

} 

in diesem Fall jobCategories und Sport wird verwendet werden, um eine Dropdown-Box zu füllen. NumberOfchildren wird nur HTML eingefügt werden und ich will es nicht editierbar. Wenn ich schreiben will ich will nur mit nur den gebuchten Eigenschaften ein schlankes Objekt zu übergeben zurück, so kann ich ein anderes Objekt habe

public class PersonUpdater 
{ 
     public int Age; 
     public string FIrst; 
     public int JobCategoryId; 
} 

diese die einzigen Eigenschaften, die ich meinen Controller passieren muß, um wieder so wird wie folgt aussehen:

public ActionResult Update(PersonUpdater personUpdater) 
{ 
     _repository.UpdateModel(personUpdater). 
} 

so, die oben angegebenen, scheinen die stark typisierte Hilfsmethoden (unten) unter der Annahme, für die Art und Weise nützlich, aber dann kann auf den Server über die Entsendung zurück zu Problemen führen, wenn Sie unterschiedliche Eigenschaften referrring werden.

http://weblogs.asp.net/scottgu/archive/2010/01/10/asp-net-mvc-2-strongly-typed-html-helpers.aspx

irgendwelche Gedanken?

Antwort

7

Echte Problem ist - aktuelle akzeptierte Ansatz ignoriert SRP für Ansicht Modelle ein Bit - bearbeiten Formular wirkt als Eingabe und Ausgabe gleichzeitig.

Menschen noch nicht view model in Dividieren angenommen haben, wie ich sie nenne, input view model und output view model (für viele - auch view model Schicht schaffen, ist zu viel). Daher - Mvc2 fehlt derzeit die Unterstützung dafür (Sie haben nicht stark typisierte Ansicht, die nicht gleichzeitig Input und Output ist) hauptsächlich wegen der Unbestimmtheit und des Mangels an allgemein akzeptierten Ansätzen.

Aber ich denke, dass es einen Gewinn (ok ... es ist eigentlich ein Kompromiss) in tiefer gehen und trennen view model in 2 von ihnen. Und ich werde nicht überrascht sein, wenn diese Idee sich entwickeln und schließlich allgemein akzeptiert wird.

Eigentlich - aktuelle Ansatz hat sogar einen Namen - Thunderdome principle. Und wenn Leute wie Jeremy D. Miller das für richtig halten, wird sich die Community nicht darum kümmern und nicht nach etwas anderem suchen.


Aus praktischer Sicht - einige der Probleme, die Sie korrekten Metadaten durch die Bereitstellung mildern können (möchten Sie vielleicht fluent model metadata provider check out).

0

Sie können angeben, auf welche Eigenschaft Sie in einem stark typisierten Helfer verweisen, suchen Sie nach Überladung mit 3 Parametern.

Nichts ist falsch mit Ihrer Methode. Stark typisierte Ansichten helfen Ihnen dabei, sich besser zu entwickeln, damit kein Typus Ihnen in die Quere kommen kann.

+0

aber was ist die Eigenschaft, die Sie zum Rendern verwenden, ist anders als die Eigenschaft auf den Beitrag – leora

+0

wieder zurück, sehr rarly downvote IMO – AUSteve

+0

Ich bin glücklich zu entfernen und ändern Sie die upvote, aber es gab keine Antwort auf die Frage .. sie scheint down vote würdig – leora

-1

Meistens passt das Auto-Bindung-Zeug nicht, was ich brauche, so dass ich einfach auf einen formCollection Parameter posten und manuell gehen. Wenn Sie einen Teil des Modells verwenden können, um Magie zu binden, dann umso besser für Sie.

Bindung weniger bedeutet nicht, dass weniger Daten auf den Server zurückgeschickt werden. Alle Eingabeelemente in dem Formular werden übertragen, Sie werden sie nur nicht als diskrete, stark typisierte "automatische" Parameter sehen. Wenn Sie die Postdaten wirklich schlanker machen möchten, müssen Sie einschränken, welche Eingabeelemente sich in dem von Ihnen geposteten Formular befinden. MVC ist immer noch HTTP nach allem ...

+0

Der Downvote scheint hart, die FormCollection ist tatsächlich zurück auf die reine HTTP-Anfrage und Diese Methode funktioniert gut. Was meinst du mit "alle Arten von schlechtem"? – AUSteve

+0

ist nicht stark typisiert. . wieder welches Szenario unterstützt Model Bindung nicht? – leora

+0

Modellbindung ist gut für kleine und einfache Modelle in einfachen Szenarien, alles andere als das und die "Automagic" kann nicht bewältigen, noch war es so konzipiert, damit fertig zu werden. Das Binden von nur Papieren über die Formularsammlung der Anfrage, dh es werden diese Zeichenfolgenwerte trotzdem in die anderen Typen umgewandelt. Ich entscheide mich einfach, die zusätzlichen Funktionen nicht zu verwenden. – AUSteve

0

Ich würde vorschlagen, es einfach zu halten, indem Sie nur ein Objekt für GET und POST verwenden. Die Wartbarkeit des Codes ist hier viel wichtiger/wertvoller als das Speichern einiger Bytes für eine Aktualisierungsaktion.

Arnis macht gute Argumente in Bezug auf SRP und andere Entwurfsmuster, aber Petterns sollen angepasst werden. Wenn ich du wäre, würde ich die Hilfe benutzen, die das mvc-Framework für dich erstellt hat: benutze die getippten Helfer; Verwenden Sie typisierte Modell-/Viewmodel-Objekte für GET/POST. Wenn Sie eine komplexere Bindung benötigen, erstellen Sie einen benutzerdefinierten Binder.

Halten Sie Ihren Code Licht und Ihre App wird großartig bleiben.

+0

Sie sagen, dass die Wartbarkeit des Codes wichtig ist. Abhängig von Ihrer Denkweise ist das Erstellen separater Ansichtsmodelle für die GET- und POST-Varianten einer Ansicht der wartungsfreundlichere Ansatz. Es führt zu mehr Klassendateien und vielleicht ein wenig zusätzlichen Code, da Sie Eigenschaften in jedem duplizieren, aber Sie enden mit Objekten, die perfekt abgestimmt sind, um eine Sache gut zu machen. IMHO, das ist sauberer und daher wartungsfreundlicher als das Erstellen eines einzelnen Ansichtsmodells für GET und POST. (Es sei denn natürlich die beiden Modelle sind genau gleich, in diesem Fall diktiert Pragmatismus haben wir nur eine Klasse) –

+0

Ich denke, ich muss mit dem Seth zustimmen –

0

Ich verwende ein Modell für die Eingabe (angezeigt durch das Formular) und ein separates Modell für die Ausgabe (vom Formular gesendet). Das Ausgabemodell wird validiert. Der spezielle Grund, warum ich dies tue, ist für Dropdown-Listen. Sie möchten dem Benutzer eine Liste möglicher Werte anzeigen, die im Eingabemodell enthalten sind. In der Ausgabe oder Post aus dem Formular möchte ich nicht die Liste der möglichen Wert, möchte ich wissen, welche Werte der Benutzer ausgewählt hat, falls vorhanden.

+0

Wenn Validierung fehlschlägt, und Sie müssen das Bearbeitungsformular wieder anzeigen, wie Sie es tun Erstellen Sie das Eingabemodell, während Sie die im Ausgabemodell erfassten Änderungen beibehalten. Machst du das in der Steuerung von Hand? –

+0

Das Ausgabemodell (das ich Post benenne) hat zwei Methoden. Eine Methode gibt das Datenobjekt zurück, das bei der Validierung der Daten verwendet wird. Die zweite Methode gibt ein Objekt des Eingabemodells zurück (das ich Form nenne). Die zweite Methode wird verwendet, wenn die Validierung fehlschlägt. Ich bin gerade dabei, ein paar T4-Vorlagen zu schreiben, die diese Ein- und Ausgabemodelle für mich generieren. Sie erfordern ein manuelles Tweening, aber ich muss nicht die ganze Klasse von Grund auf neu schreiben. – 37Stars

0

Ich verwende separate Ansichtsmodelle für Eingabe [GET] und Ausgabe [POST] auch, wenn die beiden Modelle identisch sind. Meiner Meinung nach ist dieser Ansatz sauberer, einfacher zu pflegen und gibt klarer zum Ausdruck, welche Daten durch eine bestimmte Controller-Aktion aktualisiert werden.

Es gibt eine Kosten in Bezug auf LOC, aber der zusätzliche Code ist in der Regel nicht Logik. In den meisten Fällen habe ich nicht das Gefühl, dass das Duplizieren einiger automatischer Eigenschaften auf zwei Objekten gegen das DRY-Prinzip verstößt, und ich denke, dass die Kosten gerechtfertigt sind, um SRP zu folgen.

Die anderen Kosten, wie Sie bemerkt haben, ist, dass die eingebauten stark typisierten Helfer nicht so gut funktionieren. Hast du darüber nachgedacht, eigene Helfer zu schreiben, die dein Muster unterstützen? Sie könnten beispielsweise einen der vorhandenen Helfer überlasten, so dass Sie sowohl die Quelle (z. B. die Eigenschaft des Eingabemodells) als auch das Ziel (z. B. den Namen des Formularfelds, das an das Ausgabemodell gesendet wird) angeben können).

0

Wenn ich nur auf Ihre spezifische Situation schaue, fallen mir die folgenden Punkte auf.

1) Die beiden Modelle sind sehr ähnlich in der Tat 2) Wenn Sie „Middle“ hinzufügen, müssen Sie es an zwei Stellen 3) hinzufügen Wenn Sie sagen: „Ich will nur ein schlankes Objekt übergebe zurück“ - die Der tatsächliche POST enthält die gleiche Datenmenge, unabhängig davon, ob Sie an das ursprüngliche Modell oder an ein neues binden (es enthält einen Schlüssel, ein Wertpaar für jede Benutzereingabe innerhalb des Formulars). 4) Sie schließen die Option aus, die Daten anzuzeigen auf Ihrer "gespeichert ok" oder "etwas ist nicht gültig" Seite, wie es nicht Teil des Modells ist

Aus diesen Gründen würde ich empfehlen, das gleiche Modell für die GET und POST der Aktion zu verwenden.

+0

Ich denke nicht, dass ich hier mit Ihnen einverstanden bin. Der Nachteil, Eigenschaften replizieren zu müssen, scheint es nicht zu rechtfertigen, zwei unterschiedliche Datenmodelle zu einem einzigen zu zwingen (selbst wenn es zu Überschneidungen kommt). Ich denke, es scheint viel klarer zu sein, um zu identifizieren, was an die Eingabe gebunden ist und was an die Ausgabezeile gebunden ist. – leora