2009-02-05 18 views
8

Ich bin relativ neu bei MVC, also ist dies wahrscheinlich eine Anfängerfrage.Ansichtsspezifische Modelle in ASP.NET MVC?

Ich versuche, die besten Praktiken, wie zur Aufrechterhaltung klare Trennung von Bedenken in einigen Szenarien zu verstehen, den straightfoward nicht angezeigt werden.

Es gibt zwei Szenarien, die ich gerade betrachte. Stellen Sie sich eine sehr einfache App vor, mit der Benutzer Online-Profile für Rechtsanwälte anzeigen und bearbeiten können. Es gibt eine Aktion/Ansicht zum Anzeigen eines bestimmten Benutzerprofils und eine Aktion/Ansicht zum Bearbeiten eines bestimmten Benutzerprofils. Es ist einfach, sich eine schöne und saubere Model-Klasse vorzustellen, um die Details eines Benutzerprofils darzustellen, die möglicherweise mit dem Entity Framework erstellt und der SQL-Tabelle des Benutzerprofils zugeordnet wurden.

Nach Ansicht Aktion/Ansicht für das Profil eines Benutzers anzeigt, funktionell, ich brauche eine Schaltfläche oder einen Link zu haben, die einem Benutzer bearbeiten das Profil lässt. Aber das sollte nur für einen Teil der Benutzer verfügbar sein. Zum Beispiel kann der Benutzer sein eigenes Profil bearbeiten. Außerdem können Superuser das Profil eines beliebigen Benutzers bearbeiten. Meine Frage ist, wie sollte die Ansicht entscheiden, ob der Link beim Rendern eines bestimmten Profils vorhanden sein soll. Ich nehme an, es ist falsch, dass die View die Logik enthält, um festzustellen, ob der aktuelle Benutzer das aktuelle Profil bearbeiten kann. Sollte ich der UserProfile-Modellklasse eine IsEditable-Eigenschaft hinzufügen? Das fühlt sich nicht tragisch an, aber es fühlt sich auch nicht ganz richtig an. Soll ich eine neue Model-Klasse erstellen, die das UserProfile mit zusätzlichen Informationen zur Sicherheit zusammenfasst?

Ein anderes Szenario ... Bei der Bearbeitung eines bestimmten Profils ist eines der Dinge, die bearbeitet werden können, die Liste der Spezialisierungen für einen bestimmten Anwalt. Die Liste der möglichen Spezialitäten ist nicht festgelegt. Wenn die Ansicht sie in einem Kombinationsfeld darstellen möchte, benötigt sie die Liste aller möglichen Besonderheiten aus der Datenbank. Die Ansicht sollte sie nicht direkt aus der Datenbank holen, also mache ich das Aggregatmodell noch einmal und stelle die Ansicht sowohl mit dem UserProfile als auch mit einer Liste gültiger Spezialgebiete zur Verfügung?

Ich denke, die allgemeine Frage, die ich, um herauszufinden, ich versuche ist, sollte ich mit dem Erstellen von vielen kleinen Modellklassen bequem sein, die einzelnen Ansichten im Wesentlichen spezifisch sind. Jede Klasse würde die verschiedenen nicht verwandten Teile des größeren Domänenmodells enthalten, die für diese bestimmte Ansicht benötigt werden.

Antwort

2

Für Ihr Szenario gehe ich entlang eines anderen Parameter in der Viewdata, Viewdata [ „AllowEdit“], die auf true gesetzt ist, wenn die Ansicht auf den Link Bearbeiten zeigen. Ich bevorzuge das Klonen des Modells in ein sichtspezifisches Modell, um dieses einzelne Attribut hinzuzufügen. Ich erstelle manchmal Ansichts-spezifische Modelle - zum Beispiel habe ich Grid ViewUserControl, das ein Grid-Modell verwendet, das ich aus einer beliebigen Liste anderer Modellklassen erstellen kann - aber das würde ich in diesem Fall nicht tun.

Aus meiner Sicht würde ich so etwas tun:

<% if (Convert.ToBoolean(ViewData["AllowEdit"])) { %> 
<%= Html.ActionLink("Edit", "Edit", "Profile", 
        new { id = ViewData.Model.ID }, null) %> 
<% } %> 
1

Für Ihre erste Situation, würde ich wahrscheinlich versuchen, die Logik für den im Profilmodell verkapseln, vielleicht mit einer Funktion wie CanEdit(), das akzeptiert Benutzerinformationsparameter und überprüft, ob der Benutzer der Besitzer des Profils ist oder wenn er über Superuser-Berechtigungen verfügt. Dann würde ich im Controller die Funktion aufrufen und die Ergebnisse mit ViewData an die View übergeben.

Für die zweite, in der Controller-Aktion Profil bearbeiten, Abrufen der Liste Spezialitäten (über das Modell) und gibt sie zu der Ansicht auf der Verwendung Viewdata.

0

Sie können für alle Ihre Ansicht Modellklassen eine Basismodellklasse machen und dort Informationen enthalten, die in vielen Ansicht, die in Betracht gezogen werden kann, wenn auch nicht in allen von ihnen. Zum Beispiel die ID des aktuell angemeldeten Benutzers.

public class BaseModel 
{ 
    Guid ActiveUserId; 
} 

public class EditModel : BaseModel 
{ 
    Guid AuthorUserId; 
} 

Ihrer Ansicht Dann können Sie einen grundlegenden Vergleich:

<% if (Model.ActiveUserId == AuthorUserId) 
    Response.Write (Html.ActionLink (.....)) %> 

Diese einfache Prüfung ist ganz in Ordnung, es ist nicht viel von der Logik und wie auch immer, sollte jemand entscheiden, ob dieser Link angezeigt werden soll . Sie können natürlich zwei verschiedene Ansichten machen, mit dem Link und ohne einen, aber es ist eher übertrieben.

3

ViewModel Das Muster ist speziell auf das von Ihnen beschriebene Szenario ausgerichtet. Sie können die ViewData verwenden, aber dies ist die weniger empfohlene Lösung, da Sie viele Vorteile des ASP.NET MVC-Framework verlieren. Wenn Sie z. B. ViewData verwenden, haben Sie in Ihren Ansichten keine Typsicherheit, Kompilierzeitprüfung und Intellisense-Unterstützung.