Nachdem der prinzipielle Aufbau einer ASP.NET MVC-Applikation besprochen wurde, zeigt dieser Abschnitt einige weiterführende Möglichkeiten für die Implementierung von Controllern.
Wie bereits im einführenden Beispiel gezeigt wurde, kann ASP.NET MVC die beim Aufruf übergebenen Parameter verwenden, um eine Instanz eines Models zu erzeugen. Möglich wird dies durch die sogenannte Modellbindung (engl. Model Binder). Listing 1.10 demonstriert dies.
[HttpPost] public ActionResult Edit(Hotel h) { [...] return View(); }
Listing 1.10 Controller, welcher ein Model entgegennimmt
Um zu bestimmen, welche Parameter an die Eigenschaften des Modells gebunden werden sollen, kann der jeweilige Parameter mit dem Attribut Bind
annotiert werden. Listing 1.11 demonstriert die Verwendung, indem mit der Eigenschaft Exclude
angegeben wird, dass die HotelId
beim Binden der Parameter nicht berücksichtigt werden soll. Sollen mehrere Eigenschaften ausgeschlossen werden, können diese durch Kommata getrennt angeführt werden.
Als Alternative zu Exclude
steht auch eine Eigenschaft Include
zur Verfügung. Wird diese verwendet, werden nur die angeführten Eigenschaften gebunden. Damit lässt sich verhindern, dass ein Aufrufer Werte für solche Parameter einschleusen kann, die nicht von außerhalb modifiziert werden sollen. Darüber hinaus kann mit Prefix
angegeben werden, dass die zu bindenden Parameter einen bestimmten Präfix aufweisen müssen.
public ActionResult Edit([Bind(Exclude = "HotelId")]Hotel h) { [...] }
Listing 1.11 Die Modellbindung beeinflussen
Nicht immer ist es wünschenswert, eine neue Modellinstanz von ASP.NET MVC erstellen zu lassen. In manchen Situationen ist es beispielsweise notwendig, die Modellinstanz aus einer Datenbank zu laden, um sie anschließend mit den übertragenen Parametern zu aktualisieren. In diesen Fällen kann die Auflistung FormCollection
als Parameter verwendet werden. ASP.NET MVC überträgt sämtliche beim Auftrag übertragene Parameter in diese Auflistung. Anschließend können diese mit der geerbten Methode TryUpdateModel
von FormCollection
in ein beliebiges Objekt übertragen werden (vgl. Listing 1.12). Daneben existieren noch weitere Überladungen von TryUpdateModel
, welche die Angabe der vom Attribut Bind
bekannten Parameter Exclude
, Include
und Prefix
erlauben.
[HttpPost] public ActionResult Edit(FormCollection fc) { Hotel h = [...]; this.TryUpdateModel(h, fc); [...] }
Listing 1.12 Manuelles Anstoßen der Modellbindung
Bis jetzt wurde die Methode View
verwendet, um ein ActionResult
zu erzeugen, mit dem angezeigt wurde, dass an die View mit dem Namen der Action-Methode weiterdelegiert werden soll. Soll eine andere View Verwendung finden, kann, wie in Listing 1.13 gezeigt, deren Name als Parameter an View
übergeben werden. Daneben existiert auch eine Überladung, welche den View-Namen sowie das zu verwendende Modell entgegennimmt. Die angegebene View muss sich entweder im View-Ordner des Controllers oder im View-Ordner Shared
befinden.
public ActionResult Create() { [...] return View("Details"); }
Listing 1.13 Angabe der gewünschten View
Neben der Methode View
existieren noch weitere Methoden, mit welchen das Ergebnis eines Aufrufs beeinflusst werden kann. All diese haben gemeinsam, dass sie eine Instanz einer Subklasse von ActionResult
zurückliefern, welche zum gewünschten Verhalten führt. Tabelle 1.1 informiert über die Methoden dieser Klasse.
Tabelle 1.1 Methoden zur Beeinflussung des Ergebnisses
Content | Liefert den angegebenen String als Ergebnis der Anfrage zurück |
File | Veranlasst einen Download als Ergebnis |
JavaScript | Gibt den angegebenen String als JavaScript-Code zurück, der auf dem Client ausgeführt wird |
Json | Liefert das angegebene Modell JSON-formatiert zurück |
PartialView | Verwendet eine partielle View, um einen Teil einer Seite zu rendern |
Redirect | Leitet die aktuelle Anfrage zu dem angegebenen URL um |
RedirectPermanent | Wie Redirect , verwendet jedoch den HTTP-Statuscode für eine permanente Umleitung, die zum Beispiel Such-maschinen dazu bringt, den Sucheintrag mit dem Ziel der Umleitung zu verknüpfen |
RedirectToAction | Leitet die aktuelle Anfrage an die angegebene Action-Methode um |
RedirectToActionPermanent | Wie RedirectToAction , verwendet jedoch den HTTP-Statuscode für eine permanente Umleitung, die zum Beispiel Suchmaschinen dazu bringt, den Sucheintrag mit dem Ziel der Umleitung zu verknüpfen |
RedirectToRoute | Leitet die aktuelle Anfrage zu dem URL um, der zur angegebenen Route passt |
RedirectToRoutePermanent | Wie RedirectToRoute , verwendet jedoch den HTTP-Statuscode für eine permanente Umleitung, die zum Beispiel Suchmaschinen dazu bringt, den Sucheintrag mit dem Ziel der Umleitung zu verknüpfen |
Neben diesen Hilfsmethoden existieren noch ein paar Derivate von ActionResult
, die der Entwickler bei Bedarf manuell instanziieren muss. HttpStatusCodeResult
gibt zum Beispiel einen anzugebenden HTTP-Statuscode zurück. HttpNotFoundResult
retourniert hingegen den Statuscode für Not Found
.
Es besteht auch die Möglichkeit, für eventuell ausgelöste Ausnahmen eine View zu definieren, welche auf den aufgetretenen Fehler hinweist. Dazu wird, wie in Listing 1.14 demonstriert, mit dem Attribut HandleError
der Typ einer Ausnahme auf eine View gemappt. Wird dieses Attribut auf eine Controller-Klasse angewandt, gilt es für jede einzelne Action-Methode dieser Klasse.
[HandleError(ExceptionType=typeof(ArgumentException), View="Error")] public ActionResult List() { [...] }
Listing 1.14 Festlegen von Views für Ausnahmen
Damit die hier angegebene View auch tatsächlich angezeigt wird, muss der Entwickler in der Datei web.config
die Eigenschaft mode
des Elements system.web/customErrors
auf On
oder auf RemoteOnly
setzen:
<customErrors mode="RemoteOnly"/>
Die Einstellung On
bewirkt, dass die angegebene View beim Auftreten der angegebenen Exception immer angezeigt wird. Bei Einsatz der Einstellung RemoteOnly
ist dies jedoch nur dann der Fall, wenn der Aufruf nicht vom Webserver aus erfolgt ist. Somit wird sichergestellt, dass Entwickler, welche lokal testen, anstatt dieser View eine Fehlerseite mit aussagekräftigen Fehlerinformationen erhalten.
URL-Mapping beeinflussen (Routing)
Action-Methoden werden auf URLs abgebildet. Beispielsweise verweist der URL /hotel/edit standardmäßig auf die Action-Methode Edit
in HotelController
. Verantwortlich für diese Abbildung sind sogenannte Routen.
Die aktuellen Projektvorlagen sehen eine Klasse RouteConfig
mit einer statischen Methode Register-Routes
im Ordner App_Start
für die Definition von Routen vor. Damit RegisterRoutes
beim Start der Webanwendung zur Ausführung gebracht wird, rufen die Projektvorlagen diese Methode innerhalb der Methode Application_Start
auf, welche sich in der Klasse MvcApplication
befindet. Die Klasse MvcApplication
findet sich wiederum per Definition in der Datei global.asax
, welche im Root jeder ASP.NET-Anwendung vorhanden sein sollte.
Listing 1.15 zeigt die Definition der standardmäßig vorhandenen Route. Beim ersten Parameter handelt es sich um den Namen der Route, beim zweiten um den URL der Route inkl. Platzhalter für die Namen des Controllers und der Action-Methode.
Darüber hinaus findet sich am Ende der Route der Parameter id
. Der beim Aufruf für diesen Parameter angegebene Wert wird einem eventuell vorhandenen gleichnamigen Parameter der Action-Methode zugewiesen. Ein Aufruf von Hotel/Edit/7
führt somit beispielsweise dazu, dass die Action-Methode Edit
eines Controllers
mit dem Namen HotelController
aufgerufen wird, wobei – sofern vorhanden – dem Parameter id
dieser Methode...