HowTo: ASP.NET MVC Projekt erstellen (erster Einstieg)

Im letzten MVC HowTo ging es um die Beweggründe für ASP.NET MVC – heute werfen wir einen ersten Blick auf das MVC Framework. Das ganze werde ich direkt praktisch in meinem “ReadYou” Projekt verwenden (das derzeit aufgrund von Zeitmangel etwas schleift).

Die Projektvorlage:

Wenn man sich die aktuelle ASP.NET MVC Version runtergeladen hat (momentan sind wir bei Preview 5 auf Codeplex) und ein neues Projekt anlegt, sieht man folgendes neue Item:

image

Anmerkung: Wenn man das deutsche Visual Studio benutzt, scheint die Projektvorlage nicht mit aufzutauchen, dazu muss man die Project- und Itemtemplates von 1033 in 1031 (z. B. C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\ProjectTemplates\CSharp\Web\1031 bzw. \1033) kopieren und danach per Kommandozeile “devenv /installvstemplates” aufrufen. – Danke an “GarlandGreene” für den Hinweis.

Nachdem man dies ausgewählt hat kommt dieses Fenster:

image

Es wird angeboten sofort ein Unittest Projekt anzulegen. “Visual Studio Unit Test” (MS Test) ist per Default ausgewählt – später sollen allerdings noch weitere Test Frameworks (NUnit etc.) folgen.

Projektstruktur:

Nachdem die beiden Wizards durchgelaufen sind finden wir ungefähr (ich hab das UnitTest Projekt verschoben und umbenannt) so aus:

image

Aus der Ordnerstruktur ist auch bereits das MVC zu erkennen:

  • Kurzüberblick:
    • Controller: Logik
    • Models: Die eigentlichen Businessdaten
    • Views: Wie werden die Daten angezeigt

Views, Controller & Model:

Im ausgelieferten Stand besitzt das Template 2 Controller, 3 View-Ordner und ein Model-Ordner:

image

  • Im “Shared” Ordner werden alle Viewelemente gehalten, die für jeden View nützlich sind, wie z.B. die Masterpage oder eine Errorseite falls etwas schief läuft.
  • Jeder Controller besitzt seinen eigenen Ordner (“AccountController” – “Account” / “HomeController” – “Home“)
  • Diese “Pfade” können allerdings über Interfaces angepasst werden – ein Beispiel findet man z.B. hier “Partitioning an ASP.NET MVC application into separate “Areas”” oder Rob Conery Version.
  • Im Models Ordner können normale Klassen gespeichert werden – allerdings kann man diesen Ordner auch leer lassen, wenn man für die normalen Klassen bereits eine Klassenbibliothek hat.

Ein Blick auf die Seite:

Um einen ersten Blick auf die Funktionsweise des MVC Frameworks zu erhaschen ist die Startanwendung (welche bereits mit dem Membershipsystem, Masterpages etc.) ausgeliefert wird, ein guter Anfangspunkt:

image

image

Der Request Flow:

Justin Etheredge hat auf seinem Blog gut dargestellt, wie der Request einer MVC Anwendung verarbeitet wird und wo es überall die Möglichkeit gibt, selber einzugreifen: ASP.NET MVC Request Flow

Kommunikation zwischen Controller und View: Vom Controller zum View

image

 

Der Controller wird durch den Request Flow (siehe oben) aufgerufen – ich werde später noch eigene Controller in einem seperaten HowTo erstellen. Dabei kann man das ViewData Dictionary nutzen:

public ActionResult Index()
        {
            ViewData["Title"] = "Home Page";
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();
        }

Durch den Aufruf der “View()“-Methode wird der View namens “Index” (weil die ControllerAction “Index” heisst) im “Home” Ordner aufgerufen (weil der Controller “Home” heisst).

Im View “Index.aspx” ist folgender Quellcode:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ReadYou.WebApp.Views.Home.Index" %>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData["Message"]) %></h2>
    <p>
        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    </p>
</asp:Content>

Durch das einbinden der Masterpage (“MasterPageFile”) wird natürlich auch die Masterpage aufgerufen:

...
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <title><%= Html.Encode(ViewData["Title"]) %></title>
</head>
...

Die Daten in dem “ViewData” werden sowohl in der Masterpage als auch in dem eigentlichen View angezeigt – ähnlich wie bei klassischem ASP.

Stark Typisierte Variante

Da das Dictionary nicht besonderes typisiert ist, kann man natürlich die ViewData auch noch streng typisiert hinterlegen. Dafür muss man in der Codebehinde Datei der ViewPage, welche im Ausgangszustand so aussieht:

namespace ReadYou.WebApp.Views.Home
{
    public partial class Index : ViewPage
    {
    }
}

Einen eigenen ViewData Typ hinterlegen:

Index.aspx.cs:

namespace ReadYou.WebApp.Views.Home
{
    public class IndexViewData
    {
        public string Text { get; set; }
    }

    public partial class Index : ViewPage<IndexViewData>
    {
    }
}

Index.aspx:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ReadYou.WebApp.Views.Home.Index" %>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2><%= Html.Encode(ViewData.Model.Text) %></h2>
    <p>
        To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
    </p>
</asp:Content>

HomeController.cs:

        public ActionResult Index()
        {
            ViewData["Title"] = "Home Page";
            IndexViewData data = new IndexViewData();
            data.Text = "Hallo streng typisierter Text";
            ViewData.Model = data;
            return View();
        }

Hinweis: Das ViewData["Title"] wird nach wie vor von der Masterpage ausgewertet. In einer MVC Anwendung müssen alle Daten vom Controller übergeben werden – es existiert momentan (Preview 5) nur eine experimentelle Funktion, welche es erlaubt, dass der View sich Daten aus anderen Quellen holt – allerdings entspricht dies nicht der MVC Norm!

Mehr Informationen findet man in dem Blogpost von Scott Guthrie (damals Preview 3 – Konzept ist gleich geblieben, manche Sachen sind allerdings geändert wurden):
ASP.NET MVC Framework (Part 3): Passing ViewData from Controllers to Views

 

Kommunikation zwischen Controller und View: Vom View zum Controller

image 

Der View kann über normale Links oder HTML Formulare die Daten an einen Controller schicken. Ein Beispiel ist bereits in dem Template eingebaut: Der Login-Mechanismus – dafür schauen wir uns die Login.aspx an:

Variante 1: Per GET oder der “ActionLink”

Für alle die noch nicht angemeldet sind, gibt es auf der Loginseite einen kleinen Link zum Registrieren:

image

Im Code:

<p>
        Please enter your username and password below. If you don't have an account,
        please <%= Html.ActionLink("register", "Register") %>.
    </p>

Dieser Html Helper generiert den Link damit die Daten beim Klicken zum “AccountController” (der View befindet sich im “Account” Ordner) zur “Register” ActionMethode kommen.

Variante 2: Per POST

Der Username / Password wird in einem normalen Html Forumlar eingegeben:

    <form method="post" action="<%= Html.AttributeEncode(Url.Action("Login")) %>">
        <div>
            <table>
                <tr>
                    <td>Username:</td>
                    <td><%= Html.TextBox("username") %></td>
                </tr>
                <tr>
                    <td>Password:</td>
                    <td><%= Html.Password("password") %></td>
                </tr>
                <tr>
                    <td></td>
                    <td><input type="checkbox" name="rememberMe" value="true" /> Remember me?</td>
                </tr>
                <tr>
                    <td></td>
                    <td><input type="submit" value="Login" /></td>
                </tr>
            </table>
        </div>
    </form>

Die action-URL wird wieder über einen Html Helper generiert. Wenn der Nutzer das Formular abschickt, kommen die Daten in der “Login” ActionMethode des “AccountControllers” an:

        public ActionResult Login(string username, string password, bool? rememberMe)
        {

            ViewData["Title"] = "Login";

            // Non-POST requests should just display the Login form 
            if (Request.HttpMethod != "POST")
            {
                return View();
            }

            // Basic parameter validation
            List<string> errors = new List<string>();

            if (String.IsNullOrEmpty(username))
            {
                errors.Add("You must specify a username.");
            }
...
        }

Es gibt im MVC Framework einen eingebauten Mechanismus, der Formularwerte direkt auf Methoden-Parameter mappen kann (dies ist (natürlich) auch anpassbar). Dies ist nützlich, damit man die Methode besser mit UnitTests testen kann und kein Request Objekt sich erzeugen muss, sondern nur die Parameter entsprechend befüllen.

In der Methode werden Validierungen etc. vorgenommen. Man kann hier auch auf das normale Request Objekt zugreifen – allerdings sollte man um eine hohe Testbarkeit zu erreichen nicht direkt auf die Request Parameter zugreifen, sondern versuchen das Parametermapping zu verwenden. Stephen Walther hat dazu ein netten Blogpost darüber geschrieben.

Die Html Helper können auch “streng typisierte” sein und somit braucht man nicht unbedingt mit Strings Arbeiten (bei dem Actionlink z.B. direkt den Methodenaufruf über eine Expression anstatt “Register” als String zu schreiben) – Scott Hanselman hat einen Screencast dazu gemacht.

“Best Practices”, Tipps und Anlaufstellen

Da das MVC Framework noch nicht mal Beta ist, gibt es natürlich noch keine “Best Practices” – allerdings gibt es bereits mehrere interessante Projekte, welche mit MVC erstellt werden und Tipps geben:

Im nächsten HowTo werde ich dann genauer auf einzelne Teile eingehen – dies soll als Einstieg genügen.

Wenn dir der Blogpost gefallen hat, dann hinterlasse doch einen Kommentar. Wenn du auf dem Laufenden bleiben willst, abonniere unseren RSS Feed oder folge uns auf Twitter.

About the author

Written by

Hi, ich bin Robert Mühsig und bin Webentwickler und beschäftige mich mit Web-Frameworks auf dem Microsoft Web Stack und scheue mich auch nicht vor Javascript. Der Blog begann als "Problemsammelstelle und Lösungshilfe" und seitdem schreibe ich hier alles auf. Seit 2008 bin ich Microsoft MVP für ASP.NET. Treffen kann man mich online via Twitter (@robert0muehsig) oder hier.

6 Responses

  1. Hallo Robert

    Die Codecamp Applikation passt hier sicherlich auch noch gut rein. Das ist eine schöne Referenzapplikation für ASP.NET MVC:
    - http://code.google.com/p/codecampserver/

    Reply

Comment on this post

Letzte Posts

  • image.png
    Source Code veröffentlichen – aber bitte mit Lizenz

    Seit es den Blog gibt wird auch meist der gesamte Demo Source Code mit veröffentlicht. Das Ganze hatte ich am Anfang noch als .zip verteilt, später lag es mal auf Google Code und nun liegen alle Samples und sonstige Sachen auf GitHub. Beim letzten User Group Treffen in Zürich mit dem Titel “Open Source: Get […]

  • Fix: Cannot convert from ‘CConnectProxy::_ComMapClass *’ to ‘AddInDesignerObjects::IDTExtensibility2 *’

    Mal einen etwas esoterischer Blogpost, welcher auftaucht wenn man zu viel mit Office Addins rumspielt. Der Fehler passiert beim Bauen von C++ Projekten, welchen diesen Typ benötigen. Lösung (auf 64bit Systemen): C:\Program Files (x86)\Common Files\DESIGNER>regsvr32 MSADDNDR.DLL And Rebuild. Meine lieben Kollegen hatte mir dies schon mehrfach gesagt, allerdings hatte ich es immer wieder vergessen Das […]

  • Gegen das Gesetz verstoßen: X Jahre Haft. Gegen die Terms of Use verstoßen: Bann auf Lebenszeit. Danke Google & co.

    Bei fast allen Diensten die man im Internet nutzen kann muss man den “Terms of use” zustimmen. Völlig logisch dass da natürlich drin steht was erlaubt und was nicht. Wenn man gegen diese Regelungen verstößt hat das Unternehmen natürlich das Recht etwas dagegen zu unternehmen. In der heutigen Welt beherrschen einige wenige Unternehmen die digitale […]

  • image.png
    RSS Feed samt Kommentaranzahl und andere nicht Standard Elemente mit dem SyndicationFeed auslesen

    Jetzt mal ein Blogpost ohne ein fancy NuGet Package: Seit .NET 3.5 gibt es die SyndicationFeed Klasse. Eine schon etwas ältere API, reicht aber aus um Atom bzw. RSS Feeds zu lesen. In diversen RSS Feeds gibt es aber Erweiterungen, welche man natürlich auch auslesen möchte. So gibt WordPress z.B. auch die Anzahl der geposteten […]

  • image.png
    ASP.NET Bundling & Fontawesome

    Vor einer halben Ewigkeit hatte ich mal geschrieben wie man Fontawesome in ASP.NET nutzen kann. Aufgrund des Alters des Post und einem Kommentar ob man denn Fontawesome auch in das ASP.NET Bundling Framework integrieren kann möchte ich nur ein kurzes Update schreiben. TL;DR: NuGet Package “Fontawesome” runterladen und Pfad in der Bundleconfig angeben. Kurze Schritte […]

Amazon Shop

Facebook