Sunday 1 November 2009

MVC How Cool Is That?!

Possibly one of the coolest things to happen to ASP.NET in the last year is the MVC, which stands for Model View Controller which are the three main elements to this new technology. The first thing that strikes me about MVC is the efficiency of it. With very little work a developer can put together web applications which would have taken much more effort with standard ASP.NET.

Model
Most developers are now used to building a data access layer for their applications. The 'Model' part of the MVC is just this. My personal preference is to use Linq to SQL here in pretty much exactly the same way as I've been doing since Linq emerged. It seems slightly off topic to go into this further as building a data access layer for use in MVC is exactly the same as building a data access layer for any ASP.NET application. The one difference is that all your model classes should reside inside the 'Model' folder which is located in the root of the application. If you're using Visual Studio and have created a new MVC project, the Model folder should have been created for you.

When you need to access methods from these classes you must reference them in exactly the same way as you would do normally in .NET development.

View
The view is the actual .aspx page which is loaded in the browser. To make things a little clearer, lets assume we're dealing with a part of an application managing user information. By default we can choose from several view templates intended to represent CRUD screens (Create, Read, Update and Delete). These pages are intended to have a minimal amount of code in them - just enough to display whatever data is required. Data can be passed to the view as either ViewData (which is used in a similar way to ViewState, eg. ViewData["Employees"]) or by generating a strongly typed View and passing an object directly to it. The code for doing either of these things is in the Controller which I'll cover below.

A view can have a master page, which can in turn have many other master pages, just like in ASP.NET. Probably the most distinctive thing about a View is how data is rendered to the page.

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>
<div>
<%= Html.Encode(ViewData["Employees"]) %>
</div>

Here we see a very basic example of displaying some data from the ViewData which could have been passed to the page from a Controller. What's of note is that the output is entered in-line which although not unusual for ASP.NET, is very much the main mode of controlling output to the page within MVC. Here's an example of adding data to the screen using strongly typed View.

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable
<MvcApplication1.Models.Movie>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Index
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Index</h2>
<table>
<tr>
<th></th>
<th>
Id
</th>
<th>
Title
</th>
<th>
Director
</th>
<th>
DateReleased
</th>
</tr>
<% foreach (var item in Model) { %>
<tr>
<td>
<%= Html.ActionLink("Edit", "Edit", new { id=item.Id }) %> |
<%= Html.ActionLink("Details", "Details", new { id=item.Id })%>
</td>
<td>
<%= Html.Encode(item.Id) %>
</td>
<td>
<%= Html.Encode(item.Title) %>
</td>
<td>
<%= Html.Encode(item.Director) %>
</td>
<td>
<%= Html.Encode(String.Format("{0:g}", item.DateReleased)) %>
</td>
</tr>
<% } %>
</table>
<p>
<%= Html.ActionLink("Create New", "Create") %>
</p> </font>
</asp:Content>


Notice how MVC relies much more on writing ACTUAL HTML as opposed to dragging server controls onto the page and tying them into a code behind page. For many of us this is a welcome return to the nuts and bolts of what the internet is all about.

It is also possible to generate HTML output directly from HtmlHelper classes which can be called directly from the page. In this way the way the page is built is turned on its head; instead of writing code behind to insert controls into place holders we're calling the class which will return the required XHTML directly from the location we want to use it. For developers who remember the days of classic asp this will be familiar ground.

Controller
A Controller is the thing which accepts your web request and builds the response using Models and Views. Below is an example of a Controller with two actions, both returning different Views.
namespace MVCApp.Controllers
{
public class ItemController : Controller
{
//
// GET: /Item/
public ActionResult Index()
{
// Add action logic here
return View();
}

//
// GET: /Item/Detail/4
public ActionResult Detail(int? id)
{
if(!id.HasValue)
RedirectToAction("Index");

return View(model.getDetailFromID(id));
}
}
}



This Controller has two actions, Index() and Detail(). The views which this Controller maps to MUST be in the folder \Views\Item\ in the root of the application. There is nothing else but the name of the controller mapping this controller to the Item folder so it is essential that the controller is named correctly. Also, it must be suffixed with the word 'Controller' otherwise it will not work.

The View() referenced in the Index() Action is the file \Views\Item\Index.aspx and the View referenced by the Detail() Action is \Views\Item\Detail.aspx. The only thing linking these Actions to the Views is the name, so again this is critical to the operation of the application.

Index() simply returns the Index view without passing any data to it. The Detail() action, however, pulls data from the modal and passes it to the Detail View which can access the data as in the strongly typed view example above (foreach (var item in Model)...).

An action can be accessed by a Form Post, an AJAX call or both. If an action is called using AJAX then it's most likely you'll want to return a PartialView rather than a full View. A partial view should map to a .ascx file in the relevant Views folder. You could also return JSON instead of HTML. In fact there are several different types of data which can be returned as an ActionResponse. You'll find excellent coverage of Actions and what can be included in an ActionResponse here.

Templates
Finally I want to mention the templates which can be found below the Common7 folder of Visual Studio (have a search for a folder called MVC). When a new View is generated, the developer is asked to choose what template is used. By default the templates listed in this folder are offerred up as options. Copying the Templates folder into the root of your application will override the default options and allow you to generate your own templates based on the original ones. In order for your application to build however, you must first set the Build Behaviour of the templates to 'None'.

Although the templates are not particularly well advertised, for larger projects these will undoubtedly become more important. It should be noted that once a View or Controller (both can be templated) has been generated from a template, altering the template will not alter the generated file. This means it's important to set up your templates before generating files. It's also important to understand that these do not replace Master Pages. Templates should only control the bare minimum amount of markup required to output data to the page in a usable format.

This has really been a very brief overview of MVC. Some excellent tutorials can be found at http://www.asp.net/learn/mvc/ (the examples here originated there) and Scott Hanselman has made a must see video at http://www.asp.net/learn/mvc-videos/video-7093.aspx. Scott's Nerdinner video is the perfect place for experienced developers to start with MVC, I can't recommend it enough.


No comments:

Post a Comment