Da im letzten Artikel der Design Patterns Reihe ASP.NET MVC aufgekommen ist will ich hier eine kurze Einführung in das neue ASP.net MVC Framework zu geben, da sich einige Folgeartikel auch noch darauf stützen werden.
Die Möglichkeiten, die dieses Framework mitbringt, sind natürlich viel zu umfangreich für einen Blog Post, deshalb habe ich am Ende des Posts ein paar Referenzen zusammengetragen. Die, dem (ASP.NET) MVC Pattern zugrundeliegende Idee ist einfach und millionenfach bewährt: Folgende Komponenten interagieren dabei mit einander:
- Model: Bilden die Business- oder Domainobjekte ab. Sollten als reine "Datencontainer" ohne jegliche Logik implementiert sein.
- Views: Stellen das User Interface dar. Dies sind die HTML Seiten die von den Controllern mittels den Daten aus den Models generiert und zum Client Browser gesendet werden.
- Controller: Dies sind die Schnittstellen zwischen Views und Benutzerinteraktionen in den Views und der eigentlichen Programmlogik. Controller nehmen Eingaben entgegen und entscheiden welche View mit welchen Daten generiert wird. Generell sollten Controller ihre Aufgaben an "Services" weiterreichen, welche die Daten verarbeiten (speichern / laden,..)
Ein radikales Umdenken von der klassischen ASP.NET Entwicklung mit "Code-Behind" ist auf jeden Fall angesagt. Funktionen werden nicht über die View aufgerufen sonder genau umgekehrt. Es gibt keine Code-Behind Files mehr! Views enthalten reines HTML und spezielle "HtmlHelper" Controls. Während man bei ASP.NET immer sehr “ASPX Seiten” – lastig denkt, muss man hier seinen Fokus auf die Controller legen, da diese die Views erzeugen und die Views (ASPX Seiten) wirklich keine Programmlogik sondern nur Layout enthalten.
Wie sieht das ganze in meinem [Insert Favourite IDE] :-) aus? Ende der Theorie, am einfachsten ist es immer sich Sourcecode anzusehen um neue Frameworks etc. zu verstehen. Also hier nun ein kleines Beispiel:
Das ASP.net MVC Web Application Template erstellt automatisch die benötigte Ordnerstruktur und konfiguriert die Routing Regeln. Weiters werden (wie bei VS Templates üblich) Beispiel Dateien (Views und Controller angelegt.
Mittels Routing Regeln werden URLs in Controller Actions umgewandelt. In Global.asax wird beim Template automatisch eine Default Routing Regel eingetragen.
"{controller}/{action}/{id}[/{Parameter}]"
Controller einer einfachen Index.aspx Seite, wie sie vom MVC Template für Visual Studio angelegt wird.
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!"; return View();
}
public ActionResult About()
{
return View();
}
}
Der Aufruf http://[SERVER]/Home/Index würde die Methode Index im HomeController ausführen. Wobei die spezielle Index Methode automatisch ausgeführt wird wenn nichts übergeben wird. Somit http://[SERVER]/Home ist äquivalent zum vorherigen Die About Methode wird über http://[SERVER]/Index/About aufgerufen.
Es ist wichtig zu verstehen, dass die Controller Klassen (by default) immer den Namen [Name]Controller tragen und die Views im "Views" Verzeichnis der Solution in einem Unterverzeichnis liegen dessen Name dem Controllernamen entspricht. Die Views von HomeController.cs liegen in ~/Views/Home. (siehe Abb. 2)
Ein Aufruf http://[SERVER]/Home/Index führt nun im HomeController die Methode Index() aus welche standardmässig mittels return View(), Index.aspx aus ~/Views/Home zurückliefert . Ebenso liefert return View() in der Methode About() die View About.aspx aus ~/Views/Home.
Daten werden mittels des ViewData Objekts an die View übergeben stehen somit in der ASPX Seite zur Verfügung. Weiters steht in jeder View ein generisches Property namens Model zur Verfügung, welches die Instanz des gerade angezeigten Models enthalten sollte (Also die Instanz des Businessobjekts welches man bearbeitet, anzeigt, ..).
Der string welcher in der obigen Index Methode in ViewData gespeichert wird, steht in der View (Index.aspx) folgendermassen zur Verfügung:
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
Das Verarbeiten von Eingaben, also "Form Posts" ist auch ganz einfach (und sehr elegant finde ich :-))
< Die Werte der Steuerlemente, die mittels den HTML Helper Klassen erzeugt werden, können einfach als Parameter an die entsprechende Controller - Methode angefügt werden. Die Werte der Steuerelemente werden vom MVC Framework automatisch auf die Parameter gemappt und stehen somit in der Methode typisiert zur Verfügung.
<%= Html.TextBox("userName") %>
<%= Html.TextBox("email") %>
<%= Html.Password("password") %>
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(string userName, string email, string password)
{
...
} Noch einfacher geht’s so:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(User newUser)
{
...
}
In diesem Fall muss das Businessobjekt User die Properties userName, email und password enthalten. Die Werte aus den Steuerelementen werden dann automatisch auf eine neue Instanz von User gemappt.
Natürlich kann auch ganz "traditonell" einfach das ViewData Objekt verwendet werden. Zum Beispiel ViewData["email"] um den Wert des Steuerelements "email" auszulesen. Das AcceptVerbs Attribut, das ich oben verwendet habe, besagt einfach, dass diese Methode nur via "POST" und nicht via "GET" aufgerufen werden kann.
Auch das Editieren ist ein sprichwörtlicher Dreizeiler:
public ActionResult Edit(FormCollection values)
{
UpdateModel(values);
DataBase.AcceptChanges(Model)
return View();
}
Hier werden die Eingabewerte aus der FormCollection auf die Properties das aktuellen "Models" der View gemappt.
Auf der diesjährigen VSOne Konferenz in München wird es eine Session zu ASP.NET MVC geben, wer interessiert ist – vorbeischauen.
Hier noch ein paar Referenzen, die nach diesem Teaser interessant sein könnten:
Offizielle ASP.net MVC Page
MvcContrib - Must Have! Zusätzliche Steuerelemente (Grid) und vieles mehr
Gutes Tutorial zur Verwendung von jQuery mit dem MvcContrib Grid, und hier noch eines zum MvcContrib Grid