HowTo: First steps with ASP.NET MVC

In my last post I wrote about why you should take a look at ASP.NET MVC. With this blogpost I want to go a little bit deeper into the MVC universe.

The project template
After the installation of ASP.NET MVC (currently beta) you will find a new project template in Visual Studio:

image_thumb1

Right after you click ok you get another dialog:

image_thumb5

ASP.NET MVC is very testable and ask you if you want to create a unit test project. I recommend you to do that (or create your own unit test project) – unit tests are a great way to produce high quality.
The default test framework is MSTest, other frameworks will be added later (hopefully :) ).

Project structure:
Now you should see a solution like this (i added another project to this solution, but you don´t need to care about it):

image_thumb7

The "ReadYou.WebApp" shows the typical ASP.NET MVC folder structure:

  • Controller: Logic
  • Models: Business data / application model
  • Views: simple ASPX / ASCX / masterpage (or other) views

Views, Controller & Models in detail
The project template include 2 controller and 3 view folders:

image_thumb9

  • The "Shared" folder contains all viewelements that could be used by other views, like the masterpage or some common controls.
  • Each controller has it´s own view folder ("AccountController" – "Account" / "HomeController" – "Home")
  • This "path"-configuration can be modified by using the diverent interfaces, hier are 2 good examples "Partitioning an ASP.NET MVC application into separate "Areas"" and Rob Conerys version.
  • The "model" folder contains only the application data classes (normal CRL classes)

A short look on the default website:
The default MVC website is great to get a first look how MVC is working. There is masterpage, a simple membershipsystem and some simple form stuff (the login and register page) :

image_thumb14

image_thumb13

The request Flow:
Justin Etheredge create a great overview of the request flow and where the extensibility points are: ASP.NET MVC Request Flow

Communication between the controller and the view:

image_thumb31

You can use the "ViewData"-dictionary to send data from the controller (the request will be routed to an action method of a controller) :

  1. public ActionResult Index()  
  2.         {  
  3.             ViewData["Title"] = "Home Page";  
  4.             ViewData["Message"] = "Welcome to ASP.NET MVC!";  
  5.  
  6.             return View();  
  7.         } 

The data in the dictionary  will be send to a view called "Index" in the "Home" folder, because the action method is a method of the "HomeController". You can specify a view in the "View(YOURVIEW)" method, but if you just use the "View()" method the MVC framework will route the data to a view namend like the action method itself e.g. "Index".

Source code of the "Index.aspx" (~/Views/Home/):

  1. <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ReadYou.WebApp.Views.Home.Index" %>  
  2.  
  3. <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">  
  4.     <h2><%= Html.Encode(ViewData["Message"]) %></h2>  
  5.     <p>  
  6.         To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.  
  7.     </p>  
  8. </asp:Content> 

The data in the "ViewData"-dictionary are rendered though the inline code. There is no code behinde file, it´s similar to PHP/JSP or classic ASP.

As you can see: ASP.NET MVC is still MVC. You can still use the masterpage files and the content placeholder and use the "ViewData" in the masterpage:

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

Strongly typed ViewData:

The dictionary isn´t very great in bigger applications, but you can use a strongly typed ViewData class to send data from the controller to the view. If you take a look at the code behinde file of the viewpage, than you see a partial class which is inherited from ViewPage:

  1. namespace ReadYou.WebApp.Views.Home  
  2. {  
  3.     public partial class Index : ViewPage  
  4.     {  
  5.     }  

You can pass in your own "ViewData" class to the ViewPage<T>:

Index.aspx.cs:

  1. namespace ReadYou.WebApp.Views.Home  
  2. {  
  3.     public class IndexViewData  
  4.     {  
  5.         public string Text { get; set; }  
  6.     }  
  7.  
  8.     public partial class Index : ViewPage<IndexViewData>  
  9.     {  
  10.     }  

Index.aspx:

  1. <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="ReadYou.WebApp.Views.Home.Index" %>  
  2.  
  3. <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">  
  4.     <h2><%= Html.Encode(ViewData.Model.Text) %></h2>  
  5.     <p>  
  6.         To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.  
  7.     </p>  
  8. </asp:Content> 

HomeController.cs:

  1. public ActionResult Index()  
  2. {  
  3.     ViewData["Title"] = "Home Page";  
  4.     IndexViewData data = new IndexViewData();  
  5.     data.Text = "Hi strongly typed viewdatat";  
  6.     ViewData.Model = data;  
  7.     return View();  

The benefit of this approach is, that you get a more robust application and have a "contract" between the view and the controller.

Warning: The "ViewData["Title"]" is still in use, because the masterpage needs this data. In the MVC universe the controller is responsible to send all data to the view (there are some ideas how you can create an get an independent control).

You finde more information in this great blogpost of Scott Guthrie (it´s an older one, but the concepts are still in use):

ASP.NET MVC Framework (Part 3): Passing ViewData from Controllers to Views

Communication between the view and the controller

image_thumb30 

The view talks to the controler via normal HTML links or forms (GET/POST data).

The template included some examples:

Option 1: Via GET or the "ActionLink"

If you want to go to the register page, you just click on this link:

image_thumb28

You just use the HTML "ActionLink" helper:

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

The request will be routed to the "Register" action method on the "AccountController", because this view is inside the "Account"-folder and the second ActionLink parameter contains the name of the specific action method.

Option 2: Via POST

The login mask (username / password) use a standard HTML form:

  1. <form method="post" action="<%= Html.AttributeEncode(Url.Action("Login")) %>">  
  2.     <div>  
  3.         <table>  
  4.             <tr>  
  5.                 <td>Username:</td>  
  6.                 <td><%= Html.TextBox("username") %></td>  
  7.             </tr>  
  8.             <tr>  
  9.                 <td>Password:</td>  
  10.                 <td><%= Html.Password("password") %></td>  
  11.             </tr>  
  12.             <tr>  
  13.                 <td></td>  
  14.                 <td><input type="checkbox" name="rememberMe" value="true" /> Remember me?</td>  
  15.             </tr>  
  16.             <tr>  
  17.                 <td></td>  
  18.                 <td><input type="submit" value="Login" /></td>  
  19.             </tr>  
  20.         </table>  
  21.     </div>  
  22. </form> 

The Url.Action Helper create the action URL for the form. The form values will be submitted to the "Login" action method of the "AccountController", beacuse this view is inside the "Account"-folder.

The source code of the "Login" action method:

  1.         public ActionResult Login(string username, string password, bool? rememberMe)  
  2.         {  
  3.  
  4.             ViewData["Title"] = "Login";  
  5.  
  6.             // Non-POST requests should just display the Login form   
  7.             if (Request.HttpMethod != "POST")  
  8.             {  
  9.                 return View();  
  10.             }  
  11.  
  12.             // Basic parameter validation  
  13.             List<string> errors = new List<string>();  
  14.  
  15.             if (String.IsNullOrEmpty(username))  
  16.             {  
  17.                 errors.Add("You must specify a username.");  
  18.             }  
  19. …  
  20.         } 

The form values are automatically mapped to the method parameters. This mapping could be modified. Stephen Walther wrote a nice blogpost about this. And there is a great screencast how the binding in ASP.NET MVC works on Dimecasts.net.

Many helpers are overloaded and take strongly typed data – just try it out :)

"Best Practices", tips and information

The MVC framework is currently a beta version, that´s why you need to search at different blogs or websites to learn more about the framework. Here are my recommendations:

Feedback

Feel free to comment this blogpost (and my english ;) )

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.

About the author

Written by

Currently there is no additional info about this author.

Recent Posts

  • Time-controlled Azure WebJobs – Azure as easy as it get‘s

        While still in development the Azure WebJob SDK offers some cool features for procession and supply of information. A good example is the sample that observes the Azure Queue and processes an item as soon as it spots one.   Scenario: time-controlled activities – without queue and so on My scenario was quite […]

  • image2021-570x194_thumb.png
    HowTo: Create RSS Feeds with ASP.NET MVC

    I’ve already written about how to consume RSS or Atom Feeds with the SyndicationFeed (in German, sry) but todays post is about how to create or publish an own feed. Beside the age of the feed standard and the much defamation from Facebook, Twitter and Google on RSS/Atom I consider this easy to consume API […]

  • image1997-311x194_thumb.png
    How to access an Azure Website with the local IIS Manager

    Since the end of February it is possible to access an Azure Website with the IIS Manager. Although the Azure Management site offers some information there are more details visible at the IIS Manager. For the connection you will need an IIS Manager and the IIS Manager for Remote Administration Extension. It’s also possible to […]

  • image1929-570x143_thumb.png
    Create and validate own Json-Web-Tokens (JWTs)

    If you are interested in web authentication you probably have heard about JSON Web tokens (JWT). What is a JWT? Maybe I’m not using the correct security termination but however: JWTs are used to exchange claims between two systems. For example: You want to log on to a service (like Facebook, Twitter, etc.) and want […]

  • Micro-Optimization: how to shrink or „embed“ pictures

      I’m currently working on the “CodeInside Dashboard” and since the page structure isn’t that difficult it should be possible to fulfill all of Google Pagespeed or Yahoos YSlow recommendations. One of the rules was to optimize the 4 PNGs that are embedded on the page.   Before – without optimization: Below you can see […]

Support us