ASP.NET: Model, View und Controller

Microsoft will gegen Ende dieses Sommers ein alternatives Modell für ASP.NET-Anwendungen zur Verfügung stellen.

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.

Das MVC-Pattern

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.




- View: Der View-Teil kümmert sich um die Darstellung der Benutzeroberfläche inklusive der Bedienelemente und den Daten, die aus dem Model bezogen werden. View soll über keine eigene Geschäftslogik verfügen.



- Controller: Der Controller übernimmt die eigentliche Koordination zwischen Model und View. Er empfängt Benutzereingaben, reagiert auf Ereignisse, leitet die gewünschten Anforderungen (z.B. Änderungen an den Daten) an das Model weiter und wählt die im entsprechenden Kontext korrekte View-Komponente aus.



Das Diagramm unten zeigt das Funktionsprinzip des MVC-Pattern anhand einer Datenabfrage auf: Entsprechend der verwendeten URL wird der passende Controller der Webanwendung aufgerufen. Dieser fordert via Model die benötigten Daten aus einer SQL-Datenbank an und übergibt diese der passenden View. Diese wird anschliessend gerendert und zurück an den Browser geschickt. Natürlich lassen sich mit diesem Model nicht nur Daten abrufen, sondern auch Szenarien abdecken, in denen Daten manipuliert werden müssen oder Geschäftslogik angewendet werden soll.


Die Projektstruktur

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 (Customers­Controller), Produkte (ProductsController) etc. für die Handhabung der jeweiligen Datenkategorien eingerichtet werden.



Beim Erzeugen eines Projekts legt die Vorlage auf Wunsch auch gleich ein passendes Projekt zur Durchführung von Unit Tests an. Microsoft hat bei der Konzeption darauf geachtet, dass ASP.NET MVC möglichst optimal auf die testgetriebene Entwicklung (TDD) abgestimmt ist. An Test-Frameworks können neben MS Test auch NUnit oder MBUnit verwendet werden.


ASP.NET MVC in Action

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 eigentlichen Funktionen, die ein Controller ausführen kann, werden in einer Controller-Klasse in Form von sogenannten Action Methods definiert (siehe Codekasten 1). Die auszuführenden Aktionen lassen sich in der URL einbetten und werden von der URL-Routing-Engine ausgewertet und an die passende Method des Controller übergeben. Die URL /Products/Categories würde beispielsweise im Controller die Method Categories auslösen, welche eine Liste mit allen Produktkategorien anzeigt. Ausserdem kann die Routing-Engine auch Variablen aus der URL auslesen und diese als Parameter an den Controller übergeben. Die URL-Anfrage /Products/Detail/55 übergibt der Method Detail den Wert 55, um das Produkt mit der ID 55 abzurufen.



Die gezeigten Routing-Beispiele entsprechen den Standardregeln, welche in global.asax innerhalb der Applikationsklasse festgelegt sind. Mit nur wenig Aufwand lassen sich auch eigene Routing-Regeln festlegen.
Hat man die Verarbeitung der Requests via Controller definiert, kann man mit der Umsetzung der Model-Komponenten beginnen. ASP.NET lässt einem völlig offen, mit welcher Datenzugriffstechnologie oder O/R-Mapper gearbeitet werden soll. Typischerweise werden in den Klassen des Models die für eine Datenzugriffsschicht üblichen CRUD-Methoden (Create, Read, Update, Delete) eingesetzt, um mit der Datenbank interagieren zu können. Auch die übrige Geschäftslogik wird in der Model-Schicht implementiert.




Codekasten 1: Rumpf einer Controller-Klasse


Spartanische Ansichten

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


ASP.NET MVC versus WebForms

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.




Artikel kommentieren
Kommentare werden vor der Freischaltung durch die Redaktion geprüft.

Anti-Spam-Frage: Vor wem mussten die sieben Geisslein aufpassen?
GOLD SPONSOREN
SPONSOREN & PARTNER