ASP.NET: Model, View und Controller
Artikel erschienen in Swiss IT Magazine 2008/13
Web-Frameworks wie Ruby on Rails oder Django, welche auf eine moderne Architektur mit klarer Schichtentrennung auf Basis des MVC-Design-Pattern (Model, View, Controller) setzen, haben in jüngster Zeit starken Aufwind erhalten. Diesem Trend scheint sich auch Microsoft nicht mehr entziehen zu können. Mit ASP.NET MVC bringen die Redmonder in Kürze ein alternatives Programmiermodell für ihre Webtechnologie auf den Markt, welche die Architektur einer Webanwendung nach dem Model-View-Controller-Prinzip auftrennt. ASP.NET MVC wird Bestandteil der ASP.NET Extensions sein, welche wiederum zum kommenden Service Pack 1 für das .NET Framework 3.5 und Visual Studio 2008 zählen. Dieses soll gegen Ende Sommer verfügbar werden.
Bevor wir ASP.NET MVC etwas genauer unter die Lupe nehmen, sollten wir uns mit dem Grundprinzip des MVC-Design-Pattern vertraut machen. MVC basiert auf den drei elementaren Bausteinen Model, View und Controller, die nach dem Prinzip «Separation of concerns» strikt voneinander getrennt und in der Webanwendung für ein bestimmtes Aufgabengebiet zuständig sind:
- Model: Dieser Teil ist zuständig für den Umgang mit den Daten und je nach verwendetem Framework (wie auch bei ASP.NET MVC) auch für die Abarbeitung von Geschäftslogik.
Das ASP.NET-MVC-Framework stellt für Visual Studio 2008 eine entsprechende Projektvorlage bereit, mit der man den Projektrumpf einer MVC-basierten Webanwendung erzeugen kann. Die Trennung der Schichten spiegelt sich dabei in der Projektstruktur wider.
So gibt es je einen Ordner Models, Views und Controllers, in dem die einzelnen MVC-Komponenten in Form von Klassen und ASP.NET-Files definiert werden. Zum Zufügen dieser Komponenten stellt das MVC-Projekttemplate entsprechende Item-Vorlagen bereit. Um verschiedene Aufgabenbereiche klar von einander abtrennen zu können, lassen sich hier jeweils mehrere Klassen und Subordner anlegen. So können zum Beispiel neben dem HomeController, der für die Abarbeitung von Anfragen an die Homepage zuständig ist, Controller für Kunden (CustomersController), Produkte (ProductsController) etc. für die Handhabung der jeweiligen Datenkategorien eingerichtet werden.
Um das Prinzip von ASP.NET MVC aufzuzeigen, haben wir die nachfolgenden Ausführungen auf die wesentlichsten Grundfunktionen reduziert. Microsofts MVC-Framework verfügt über eine ganze Reihe von weiteren Aspekten und Funktionen, deren Erläuterung den Rahmen dieses Artikels sprengen würde. Weiterführende detaillierte Informationen zu ASP.NET MVC sind auf dem Weblog von Scott Guthrie zu finden (http://weblogs.asp.net/scottgu).
In den meisten Web-Frameworks werden Anfragen direkt einer physisch vorhandenen Datei zugeordnet. Der Aufruf http://myweb/products.aspx sorgt dafür, dass der in der Datei products.aspx Code auf dem Server abgearbeitet, gerendert und anschliessend zum Browser zurückgeschickt wird. Bei ASP.NET MVC wird dies anders gehandhabt: Eine URL-Routing-Engine wertet die eingehenden HTTP-Requests aus und leitet die Anfrage anhand der URL an den passenden Controller weiter. Die URL /Products/ würde beispielsweise dem Controller mit der Bezeichnung ProductsController zugewiesen.
Die eigentliche UI der Web-Anwendung wird, wie bereits oben angesprochen, im View-Teil implementiert. Dabei wurde das ASP.NET-MVC-Framework so konzipiert, dass es mit einer beliebigen Template-Engine (z.B. NVelocity oder Brail) arbeiten kann. Per Default wird das hauseigene ASP.NET-Modell mit ASP.NET-Seiten (.aspx), Masterseiten (.master) und User Controls (.ascx) genutzt. Die eigentlichen Views werden in Form von ASP.NET-Seiten (.aspx) implementiert. Schaut man sich eine typische View-Komponente an, fällt auf, dass die .aspx-Datei über keinen Formular-Tag und auch keine Deklarationen für Sever Controls verfügt.
MVC-Views beinhalten lediglich das notwendige HTML und die ASP.NET-Anweisungen in Form von Inline-Code, so dass man sich eher an das klassische ASP als an ASP.NET erinnert. Der Grund: MVC-Ansichten sind nur für das Generieren von Ausgaben verantwortlich. Es sind also keine Ereignisverarbeitung oder komplexen Steuerelemente erforderlich, wie es bei ASP.NET-Webforms der Fall ist. Ein ähnliches Bild liefert die zugehörige Codebehind-Datei: Es gibt keine Seiten-Init- oder Lademethoden, keine Ereignishandler, nichts, ausser der Deklaration der Basisklasse, die nicht vom Typ Page, sondern von ViewPage abstammt. Dabei handelt es sich um eine spezielle Seitenklasse für MVC-Ansichten, über die neben anderem sichergestellt wird, dass Daten via Controller an die Seite übergeben werden können.
Da bei ASP.NET MVC alle Aktionen immer via Controller abgearbeitet werden, muss auf das bewährte PostBack-Verfahren aus den klassischen ASP.NET-Anwendungen verzichtet werden. Auch die Verwendung des ViewState, welcher den aktuellen Zustand von Controls beim PostBack zwischenspeichert, wird nicht unterstützt. Bei einigen Server Controls lassen sich ASP.NET-MVC-Seiten dennoch verwenden. So zum Beispiel das leichtgewichtige ListView-Control zum Anzeigen von Daten in Listenform. Microsoft überlegt sich, bis zum Release von ASP.NET MVC einige spezielle Controls einzubauen, welche die Rückmeldungen zum Controller unterstützen.
Bei einer typischen Webanwendung erstellt man in der Regel eine Masterseite mit den Standardelementen wie Kopf- und Fusszeile und Menüs. Die eigentlichen Views (.aspx) werden dann als Platzhalter für die Masterseite implementiert. Ein Beispiel einer View auf Basis einer Mastervorlage und mit Inline-Code zeigt Codekasten 2.
Sind die Komponenten der Model- und View-Schichten komplett, lassen sie sich über den Controller zu einer vollständigen Anwendung verdrahten. In den einzelnen Aktionen des Controllers werden die benötigten Methoden im Model aufgerufen. Die zurückgelieferten Daten werden anschliessend über die RenderView-Method der Controller-Klasse der gewünschten View übergeben, gerendert und an den Browser geschickt (Codekasten 3).
Codekasten 2: Eine typische ASP.NET MVC View
Codekasten 3: Controller-Method mit Model- und View-Aufruf
Microsoft will mit ASP.NET MVC das bisherige auf WebForms basierte ASP.NET-Seiten-Modell in keiner Weise ersetzen. Vielmehr will man eine alternative ASP.NET-Architektur zur Verfügung stellen, welche vor allem in Hinsicht der klaren Trennung von Schichten wesentliche Vorteile bringt. Applikationen sind dadurch unter Umständen leichter zu warten und können einfacher auf die einzelnen Teilnehmer eines Entwicklerteams aufgeteilt werden. Ausserdem bietet das MVC-Framework eine gute Unterstützung für testgetriebene Entwicklung und bietet eine offene Architektur, so dass man auch eine eigene Template-Engine einbinden kann. Als weiterer positiver Nebeneffekt sorgt das URL-Routing-Modul quasi automatisch für «sprechende» Search-Engine-freundliche URLs.
WebForms-basierte Anwendungen bieten hingegen Vorteile, wenn es darum geht, die einzelnen Seiten schnell und einfach mit zusätzlichen Funktionen auszustatten. Durch Einschränkungen bei den Server Controls und den fehlenden Support für PostBack und ViewState wird die Entwicklung von UIs in ASP.NET MVC wesentlich aufwendiger. Immerhin lassen sich aber auch im MVC-Framework ASP.NET-Features wie beispielsweise Lokalisierung, Datenbindung, Authentifizierung, Rollen oder Datencaching weiterverwenden. Je nach Typ, Umfang und Funktionsumfang der Anwendung gilt es vorgängig abzuwägen, welches der Modelle den Anforderungen besser entspricht. Auf jeden Fall ist ASP.NET MVC ein interessantes Konzept, auf das jeder ASP.NET-Entwickler einen Blick werfen sollte.