Modell
Bei dem Modell einer MVC-Anwendung handelt es sich um eine einfache C#-Klasse. Die Daten, welche im Modell „abgelegt“ werden
sollen, werden dabei in Eigenschaften gespeichert. Die Eigenschaften müssen über den Zugriffsmodifizierer public
verfügen. Das Modell (oder auch als Datenmodell bezeichnet) wird sowohl von der Steuerung (zum Laden und Speichern der Daten)
als auch von der Ansicht (zum Anzeigen der Daten) verwendet. Datenmodelle befinden sich im Ordner Models
.
Bei Formularen, wo in der Regel auch Modelle zum Einsatz kommen, ist die Aktionsmethode meist überladen, wovon die eine für die
HTTP-Methode GET und die andere für die HTTP-Methode POST bestimmt ist. Die POST-Aktionsmethode besitzt als Übergabeparameter ein
Datenmodell. Dieses Datenmodell enthält bereits die Daten aus dem Formular. Die Daten werden dabei vom MVC-Framework mit Hilfe
der eingehenden Anfrage in dem Objekt gespeichert und an die Aktionsmethode übergeben. Deshalb kann dieses auch wieder direkt
der View()
-Methode übergeben werden. Dadurch bleiben dann die Formularinhalte erhalten. In der GET-Methode wird im
Regelfall (und nur in Bezug auf Formulare) eine „einfache“ Objektinstanz übergeben, andernfalls müssten alle Zugriffe auf das
Datenmodell in der Ansicht auf null
abgefangen werden.
Um der Ansicht ein Modell zuzuweisen, notieren wir @model
gefolgt von dem Klassennamen inkl. dem Namensraum. Wollen
wir als Modell eine Liste verwenden, so können wir z. B. auch @model System.Collections.Generic.List<MeineKlasse>
notieren. Das Datenmodell wird vom Controller der Ansicht übergeben. Dafür wird das Modell-Objekt der View()
-Methode
übergeben. Um innerhalb der Ansicht auf das Modell zuzugreifen, können wir die Eigenschaft Model
verwenden. Die
Eigenschaft Model
ist null
, wenn kein Modell übergeben wurde. Im Regelfall ist eine Notation dieser
Eigenschaft jedoch nicht notwendig, da unsere Ansicht bei Verwendung eines Datenmodells nicht mehr von der Klasse ViewPage
bzw. WebViewPage
abgeleitet ist, sondern von der Klasse ViewPage<TModel>
bzw. WebViewPage<TModel>
.
Um Eingabefelder, Auswahllisten etc. zu erstellen, welche in Verbindung mit einer Eigenschaft aus dem Datenmodell stehen,
nutzen wir ebenfalls HTML-Hilfsfunktionen. Jedoch verwenden wir nun z. B. an Stelle der Funktion TextBox()
die
Funktion TextBoxFor()
, statt der Funktion DropDownList()
DropDownListFor()
etc.. Alle diese
Hilfsfunktionen für die „Formularerstellung“ lassen sich also mit dem Hinzufügen von For
in den Funktionsnamen in
diese „neuen“ Hilfsfunktionen umwandeln. Bei diesen Funktionen fallen die Parameter für Feldname und Feldwert natürlich weg. Als
erster Parameter muss immer ein Ausdruck (mittels LINQ) formuliert werden, mit welcher die Eigenschaft im Datenmodell selektiert
wird. Die gerade genannten Funktionen (wie z. B. TextBoxFor()
) kommen übrigens ebenfalls nicht mehr aus der Klasse
HtmlHelper
, sondern aus der Klasse HtmlHelper<TModel>
. Diese Technologie ermöglicht uns deshalb,
dass wir uns direkt, und somit ohne weitere Angabe auf das Datenmodell, welches in der Eigenschaft Model
hinterlegt
ist, beziehen.
Das folgende Beispiel stellt ein typisches Beispiel für die Realisierung eines Kontaktformulars dar. Dabei gibt es die
Aktionsmethode Index()
im Home
-Controller, welche die Ansicht anzeigt. Der Controller und die Ansicht
greifen auf das Datenmodell, welches hier durch die Klasse Contact
beschrieben wird, zu. Auf das Speichern von
Informationen in einer Datenbank oder das Senden einer E-Mail, welches in der Aktionsmethode des Controllers durchgeführt werden
würde, haben wir aus Gründen der Übersicht und Länge des Beispiels verzichtet.
Steuerung (HomeController.cs):
using HWhBsp.Modell.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace HWhBsp.Modell.Controllers { public class HomeController : Controller { [HttpGet] public ActionResult Index() { return View(new Contact()); } [HttpPost] public ActionResult Index(Contact oContact) { return View(oContact); } } }
Modell (Contact.cs):
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace HWhBsp.Modell.Models { public class Contact { private Dictionary<string, string> _ssAnreden = new Dictionary<string, string>() { { "h", "Herr" }, { "f", "Frau" } }; public Dictionary<string, string> Anreden { get { return _ssAnreden; } } public string Anrede { get; set; } public string Name { get; set; } public string Betreff { get; set; } public string Nachricht { get; set; } } }
Ansicht (Index.cshtml):
@model HWhBsp.Modell.Models.Contact @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Modell - ASP.NET Code-Beispiel</title> <meta charset="utf-8" /> <meta name="robots" content="noindex,nofollow" /> <meta name="publisher" content="Homepage-Webhilfe" /> </head> <body> <form method="post"> <table> <tr> <td><b>Anrede:</b></td> <td>@Html.DropDownListFor(m => m.Anrede, new SelectList(Model.Anreden, "Key", "Value"))</td> </tr> <tr> <td><b>Name:</b></td> <td>@Html.TextBoxFor(m => m.Name)</td> </tr> <tr> <td><b>Betreff:</b></td> <td>@Html.TextBoxFor(m => m.Betreff)</td> </tr> <tr> <td><b>Nachricht:</b></td> <td>@Html.TextAreaFor(m => m.Nachricht)</td> </tr> <tr> <td></td> <td><input type="submit" value="Absenden" /></td> </tr> </table> </form> </body> </html>
Metadaten
Mit Hilfe von Metadaten ist es möglich, die Eigenschaften eines Modells genauer zu beschreiben. Metadaten werden in Form von
Attributen oberhalb der Eigenschaft angegeben. Die Metadaten-Attribute befinden sich im Namensraum System.ComponentModel
.
Die folgende Tabelle zeigt die wichtigsten Attribute auf:
DefaultValue | Legt den Standard-Wert der Eigenschaft fest. |
---|---|
DisplayName | Legt den Anzeigenamen der Eigenschaft fest (dieser wird u. a. bei den Standard-Fehlermeldungen verwendet). |
ReadOnly | Legt fest, dass die Eigenschaft bzw. das Feld nur gelesen werden kann. |
Neben den oben genannten Attributen gibt es noch einige weitere Attribute, die vor allem zur Validierung benutzt werden.
Diese Attribute befinden sich im Namensraum System.ComponentModel.DataAnnotations
und werden als Datenanmerkungen
(engl. data annotations) bezeichnet.
DataType | Legt den Datentyp der Eigenschaft fest. |
---|---|
Range | Legt den Wertebereich (Unter- und Obergrenze) der Eigenschaft fest. |
RegularExpression | Legt das Format in Form eines regulären Ausdrucks der Eigenschaft fest. |
Required | Legt fest, dass die Eigenschaft bzw. das Feld ein Pflichtfeld ist. |
StringLength | Legt die Zeichenkettenlänge (Unter- und Obergrenze) der Eigenschaft fest. |
Um innerhalb der Ansicht auf den festgelegten Anzeigenamen zuzugreifen, können wir die Funktion DisplayNameFor()
der HtmlHelper
-Klasse verwenden. Für einzeilige Eingabefelder empfiehlt sich zudem die Verwendung der Funktion
EditorFor()
an Stelle von TextBoxFor()
, da dadurch das type
-Attribut im input
-Element
passend zum festgelegten Datentyp gesetzt wird.
Um innerhalb der Ansicht auf die Validierungsinformation zuzugreifen, können wir die Funktion ValidationSummary()
aufrufen.
Diese gibt als Rückgabe eine Liste mit allen Fehlern zurück. Die Funktion ValidationMessage()
kann dazu
verwendet werden, um den Fehlertext für ein einzelnes Feld zurückzugeben. Die Fehlermeldungen werden entweder vom MVC-Framework
gewählt oder können über die Eigenschaft ErrorMessage
der verschiedenen Attribute festgelegt werden. Um innerhalb
des Controllers die Gültigkeit des Datenmodells zu prüfen, kann die Eigenschaft ModelState.IsValid
geprüft
werden.
Das folgende Beispiel zeigt ein erweitertes Beispiel des obigen Kontaktformulars:
Steuerung (HomeController.cs):
using HWhBsp.Modell_Metadaten.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace HWhBsp.Modell_Metadaten.Controllers { public class HomeController : Controller { [HttpGet] public ActionResult Index() { return View(new Contact()); } [HttpPost] public ActionResult Index(Contact oContact) { return View(oContact); } } }
Modell (Contact.cs):
using System; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Web; namespace HWhBsp.Modell_Metadaten.Models { public class Contact { private Dictionary<string, string> _ssAnreden = new Dictionary<string, string>() { { "h", "Herr" }, { "f", "Frau" } }; public Dictionary<string, string> Anreden { get { return _ssAnreden; } } [Required] public string Anrede { get; set; } [Required] public string Name { get; set; } [Required] [Range(6, 150)] public int Alter { get; set; } [DisplayName("E-Mail-Adresse")] [DataType(DataType.EmailAddress)] [Required] public string EMailAddress { get; set; } [Required] public string Betreff { get; set; } [Required] [StringLength(5000, MinimumLength=25, ErrorMessage="Die Nachricht muss zwischen 25 und 5000 Zeichen haben!")] public string Nachricht { get; set; } } }
Ansicht (Index.cshtml):
@model HWhBsp.Modell_Metadaten.Models.Contact @{ Layout = null; } <!DOCTYPE html> <html> <head> <title>Modell Metadaten - ASP.NET Code-Beispiel</title> <meta charset="utf-8" /> <meta name="robots" content="noindex,nofollow" /> <meta name="publisher" content="Homepage-Webhilfe" /> </head> <body> <form method="post"> <table> <tr> <td colspan="2">@Html.ValidationSummary()</td> </tr> <tr> <td><b>@Html.DisplayNameFor(m => m.Anrede):</b></td> <td>@Html.DropDownListFor(m => m.Anrede, new SelectList(Model.Anreden, "Key", "Value"))</td> </tr> <tr> <td><b>@Html.DisplayNameFor(m => m.Name):</b></td> <td>@Html.EditorFor(m => m.Name)</td> </tr> <tr> <td><b>@Html.DisplayNameFor(m => m.Alter):</b></td> <td>@Html.EditorFor(m => m.Alter)</td> </tr> <tr> <td><b>@Html.DisplayNameFor(m => m.EMailAddress):</b></td> <td>@Html.EditorFor(m => m.EMailAddress)</td> </tr> <tr> <td><b>@Html.DisplayNameFor(m => m.Betreff):</b></td> <td>@Html.EditorFor(m => m.Betreff)</td> </tr> <tr> <td><b>@Html.DisplayNameFor(m => m.Nachricht):</b></td> <td>@Html.TextAreaFor(m => m.Nachricht)</td> </tr> <tr> <td></td> <td><input type="submit" value="Absenden" /></td> </tr> </table> </form> </body> </html>