Ich habe es mir angewöhnt bestimmte in den Views immer wiederkehrende Sachen in entsprechende Basisklassen zu packen, über die ich dann einen einfache und typisierten Zugriff darauf bekomme - als Beispiel wäre der angemeldete Benutzer zu nennen. In MVC 2 sieht das dann so aus:
1: public class AppViewPage<TModel> : ViewPage<TModel>
2: {
3: private User currentUser;
4: public User CurrentUser
5: {
6: get { return currentUser ?? (currentUser = new User()); }
7: }
8: }
Anwendung:
1: <%@ Page Language="C#" Inherits="AppViewPage<ViewModel.MessageViewModel>" %>
2:
3: <% if(CurrentUser.Account.NotificationsEnabled) { %>
4: ... mach was
5: <% } %>
Nun ist in Razor ja die Deklaration der Basisklasse aus den Views verschwunden ... na ja, nicht ganz. Die globale Konfiguration steckt nun in der Web.config für den Views-Ordner (jeweils auch in jeder Area). Das Prinzip ist das Gleiche, der Typ für die Basisklasse, von dem abgeleitet werden muss, ist ein anderer. Die Razor-Variante des obigen Beispiels sieht dann so aus:
1: public abstract class AppViewPage<TModel> : System.Web.Mvc.WebViewPage<TModel>
2: {
3: private User currentUser;
4: public User CurrentUser
5: {
6: get { return currentUser ?? (currentUser = new User()); }
7: }
8: }
Wichtig ist, dass die Klasse abstract ist, da sonst die Execute-Methode von Hand implementiert werden muss - was an dieser Stelle absolut unnötig ist.
Die Registrierung (unter /Views/Web.config und ggf. /{Area}/Views/Web.config):
1: <system.web.webPages.razor>
2: <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
3: <pages pageBaseType="Blubr.App.ViewModel.AppViewPage">
4: <namespaces>
5: <add namespace="System.Web.Mvc" />
6: <add namespace="System.Web.Mvc.Ajax" />
7: <add namespace="System.Web.Mvc.Html" />
8: <add namespace="System.Web.Routing" />
9: <add namespace="Blubr.App.ViewModel" />
10: </namespaces>
11: </pages>
12: </system.web.webPages.razor>
Und die Verwendung in der View:
1: @if(CurrentUser.Account.NotificationsEnabled) {
2: mach was ...
3: }
Unterm Strich ein bisschen DRY - man spart sich halt die ständig wiederkehrende Deklaration in jeder View und kann die Klasse bei Bedarf auch einfacher austauschen. Nicht so schick gelöst finde ich, dass die Definition in jeder Web.config vorgenommen werden muss - ich habe im Moment 5 Areas + den globalen Views-Ordner, macht also 6 Stellen, an denen diese Einstellung zu pflegen ist.