Showing posts with label MVC. Show all posts
Showing posts with label MVC. Show all posts

Creating a MVC 3 Application with Razor and Unobtrusive JavaScript

The User List sample web application demonstrates how simple it is to create ASP.NET MVC  3  applications using the Razor view engine. The sample application shows how to use the new Razor view engine with ASP.NET MVC version 3 and Visual Studio 2010 to create a fictional  User List website that includes functionality such as creating, displaying, editing, and deleting users.
This tutorial describes the steps that were taken in order to build the User List sample ASP.NET MVC 3 application.  A Visual Studio project with C# and VB source code is available to accompany this topic: Download. If you have questions about this tutorial, please post them to the MVC forum.

Overview

The application you’ll be building is a simple user list website. Users can enter, view, and update user information.
Sample site
You can download the VB and C# completed project here.

Creating the Web Application

To start the tutorial, open Visual Studio 2010 and create a new project using the ASP.NET MVC 3 Web Application template. Name the application "Mvc3Razor".
New MVC 3 project
In the New ASP.NET MVC 3 Project dialog, select Internet Application, select the Razor view engine, and then click OK.
New ASP.NET MVC 3 Project dialog
In this tutorial you will not be using the ASP.NET membership provider, so you can delete all the files associated with logon and membership. In Solution Explorer, remove the following files and directories:
  • Controllers\AccountController
  • Models\AccountModels
  • Views\Shared\_LogOnPartial
  • Views\Account (and all the files in this directory)
Soln Exp
Edit the _Layout.cshtml file and replace the markup inside the <div> element named logindisplay with the message "Login Disabled". The following example shows the new markup:
 <div id="logindisplay">
  Login Disabled</div>

Adding the Model

In Solution Explorer, right-click the Models folder, select Add, and then click Class.
New User Mdl class
Name the class UserModel. Replace the contents of the UserModel file with the following code:
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
namespace Mvc3Razor.Models {
    public class UserModel {

        [Required]
        [StringLength(6, MinimumLength = 3)]
        [Display(Name = "User Name")]
        [RegularExpression(@"(\S)+", ErrorMessage = "White space is not allowed")]
        [ScaffoldColumn(false)]
        public string UserName { get; set; }

        [Required]
        [StringLength(8, MinimumLength = 3)]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }
        [Required]
        [StringLength(9, MinimumLength = 2)]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }
        [Required()]
        public string City { get; set; }

    }

    public class Users {

        public Users() {
            _usrList.Add(new UserModel
            {
                UserName = "BenM",
                FirstName = "Ben",
                LastName = "Miller",
                City = "Seattle"
            });
            _usrList.Add(new UserModel
            {
                UserName = "AnnB",
                FirstName = "Ann",
                LastName = "Beebe",
                City = "Boston"
            });
        }

        public List<UserModel> _usrList = new List<UserModel>();

        public void Update(UserModel umToUpdate) {

            foreach (UserModel um in _usrList) {
                if (um.UserName == umToUpdate.UserName) {
                    _usrList.Remove(um);
                    _usrList.Add(umToUpdate);
                    break;
                }
            }
        }

        public void Create(UserModel umToUpdate) {
            foreach (UserModel um in _usrList) {
                if (um.UserName == umToUpdate.UserName) {
                    throw new System.InvalidOperationException("Duplicat username: " + um.UserName);
                }
            }
            _usrList.Add(umToUpdate);
        }

        public void Remove(string usrName) {

            foreach (UserModel um in _usrList) {
                if (um.UserName == usrName) {
                    _usrList.Remove(um);
                    break;
                }
            }
        }

        public  UserModel GetUser(string uid) {
            UserModel usrMdl = null;

            foreach (UserModel um in _usrList)
                if (um.UserName == uid)
                    usrMdl = um;

            return usrMdl;
        }

    }    }
The UserModel class represents users. Each member of the class is annotated with the Required attribute from the DataAnnotations namespace. The attributes in the DataAnnotations namespace provide automatic client- and server-side validation for web applications.
Open the HomeController class and add a using directive so that you can access the UserModel and Users classes:
using Mvc3Razor.Models; 
Just after the HomeController declaration, add the following comment and the reference to a Users class:
public class HomeController : Controller {

        // The __usrs class is replacement for a real data access strategy.
        private static Users _usrs = new Users();
The Users class is a simplified, in-memory data store that you'll use in this tutorial. In a real application you would use a database to store user information. The first few lines of the HomeController file are shown in the following example:
using System.Web.Mvc;
using Mvc3Razor.Models;
namespace Mvc3Razor.Controllers {
       
    public class HomeController : Controller {

        // The __usrs class is replacement for a real data access strategy.
        private static Users _usrs = new Users();
Build the application so that the user model will be available to the scaffolding wizard in the next step.

Creating the Default View

The next step is to add an action method and view to display the users.
Delete the existing Views\Home\Index file. You will create a new Index file to display the users.
In the HomeController class, replace the contents of the Index method with the following code:
return View(_usrs._usrList); 
Right-click inside the Index method and then click Add View.
Add View
Select the Create a strongly-typed view option. For View data class, select Mvc3Razor.Models.UserModel. (If you don't see Mvc3Razor.Models.UserModel in the View data class box, you need to build the project.) Make sure that the view engine is set to Razor. Set View content to List and then click Add.
Add Index View
The new view automatically scaffolds the user data that's passed to the Index view. Examine the newly generated Views\Home\Index file. The Create New, Edit, Details, and Delete links don't work, but the rest of the page is functional. Run the page. You see a list of users.
Index Page
Open the Index.cshtml file and replace the ActionLink markup for Edit, Details, and Delete with the following code:
@Html.ActionLink("Edit", "Edit", new {  id=item.UserName  }) |
@Html.ActionLink("Details", "Details", new {  id=item.UserName  }) |
@Html.ActionLink("Delete", "Delete", new {  id=item.UserName  })         
The user name is used as the ID to find the selected record in the Edit, Details, and Delete links.

Creating the Details View

The next step is to add a Details action method and view in order to display user details.
Details
Add the following Details method to the home controller:
public ViewResult Details(string id) {
    return View(_usrs.GetUser(id));
}
Right-click inside the Details method and then select Add View. Verify that the View data class box contains Mvc3Razor.Models.UserModel. Set View content to Details and then click Add.
Add details view
Run the application and select a details link. The automatic scaffolding shows each property in the model.
Details

Creating the Edit View

Add the following Edit method to the home controller.
public ViewResult Edit(string id) {
    return View(_usrs.GetUser(id));
}
[HttpPost]
public ViewResult Edit(UserModel um) {

    if (!TryUpdateModel(um)) {
        ViewBag.updateError = "Update Failure";
        return View(um);
    }

    // ToDo: add persistent to DB.
    _usrs.Update(um);
    return View("Details", um);
}
Add a view as in the previous steps, but set View content to Edit.
Add Edit view
Run the application and edit the first and last name of one of the users. If you violate any DataAnnotation constraints that have been applied to the UserModel class, when you submit the form, you will see validation errors that are produced by server code. For example, if you change the first name "Ann" to "A", when you submit the form, the following error is displayed on the form:
The field First Name must be a string with a minimum length of 3 and a maximum length of 8.
In this tutorial, you're treating the user name as the primary key. Therefore, the user name property cannot be changed. In the Edit.cshtml file, just after the Html.BeginForm statement, set the user name to be a hidden field. This causes the property to be passed in the model. The following code fragment shows the placement of the Hidden statement:
<h2>Edit</h2>
    @using (Html.BeginForm()) {
        @Html.Hidden("UserName", Model.UserName)
Replace the TextBoxFor and ValidationMessageFor markup for the user name with a DisplayFor call. The DisplayFor method displays the property as a read-only element. The following example shows the completed markup. The original TextBoxFor and ValidationMessageFor calls are commented out with the Razor begin-comment and end-comment characters (@* *@)
<div class="editor-label">
  @Html.LabelFor(model => model.UserName)</div>
<div class="editor-field">
@*
  @Html.TextBoxFor(model => model.UserName)
  @Html.ValidationMessageFor(model => model.UserName)
*@
@Html.DisplayFor(model => model.UserName)</div>

Enabling Client-Side Validation

To enable client-side validation in ASP.NET MVC 3, you must set two flags and you must include three JavaScript files.
Open the application's Web.config file. Verify that ClientValidationEnabled and UnobtrusiveJavaScriptEnabled are set to true in the application settings. The following fragment from the root Web.config file shows the correct settings:
 <appSettings>
  <add key="ClientValidationEnabled" value="true"/> 
  <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 
 </appSettings>
Setting UnobtrusiveJavaScriptEnabled to true enables unobtrusive Ajax and unobtrusive client validation. When you use unobtrusive validation, the validation rules are turned into HTML5 attributes. HTML5 attribute names can consist of only lowercase letters, numbers, and dashes.
Setting ClientValidationEnabled to true enables client-side validation. By setting these keys in the application Web.config file, you enable client validation and unobtrusive JavaScript for the entire application. You can also enable or disable these settings in individual views or in controller methods using the following code:
HtmlHelper.ClientValidationEnabled = true; HtmlHelper.UnobtrusiveJavaScriptEnabled = true; 
You also need to include several JavaScript files in the rendered view. An easy way to include the JavaScript in all views is to add them to the Views\Shared\_Layout.cshtml file. Replace the <head> element of the _Layout.cshtml file with the following code:
<head>
  <title>@View.Title</title>
  <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
  <script src="http://ajax.microsoft.com/ajax/jQuery/jquery-1.4.2.min.js"></script>
  <script src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.min.js"></script>
  <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
</head>
The first two jQuery scripts are hosted by the Microsoft Ajax Content Delivery Network (CDN). By taking advantage of the Microsoft Ajax CDN, you can significantly improve the first-hit performance of your applications.
Run the application and click an edit link. View the page's source in the browser. The browser source shows many attributes of the form data-val (for data validation). When client validation and unobtrusive JavaScript is enabled, input fields with a client-validation rule contain the data-val="true" attribute to trigger unobtrusive client validation. For example, the City field in the model was decorated with the Required attribute, which results in the HTML shown in the following example:
<div class="editor-field">
  <input data-val="true" data-val-required="The City field is required." id="City" name="City" type="text" value="Seattle" />
  <span class="field-validation-valid" data-valmsg-for="City" data-valmsg-replace="true"></span>
</div>
For each client-validation rule, an attribute is added that has the form data-val-rulename="message". Using the City field example shown earlier, the required client-validation rule generates the data-val-required attribute and the message "The City field is required". Run the application, edit one of the users, and clear the City field. When you tab out of the field, you see a client-side validation error message.
City required
Similarly, for each parameter in the client-validation rule, an attribute is added that has the form data-val-rulename-paramname=paramvalue. For example, the FirstName property is annotated with the StringLength attribute and specifies a minimum length of 3 and a maximum length of 8. The data validation rule named length has the parameter name max and the parameter value 8. The following shows the HTML that is generated for the FirstName field when you edit one of the users:
<input data-val="true"         
       data-val-length="The field First Name must be a string with a minimum length of 3 and a maximum length of 8." 
       data-val-length-max="8" 
       data-val-length-min="3" 
       data-val-required="The First Name field is required." 
       id="FirstName" 
       name="FirstName" 
       type="text" 
       value="Ben" /> 
For more information about unobtrusive client validation, see the entry Unobtrusive Client Validation in ASP.NET MVC 3 in Brad Wilson's blog.
Note In ASP.NET MVC 3 Beta, you sometimes need to submit the form in order to start client-side validation. This might be changed for the final release.

Creating the Create View

The next step is to add a Create action method and view in order to enable the user to create a new user. Add the following Create method to the home controller:
 public ViewResult Create() {
            return View(new UserModel());
        }

        [HttpPost]
        public ViewResult Create(UserModel um) {

            if (!TryUpdateModel(um)) {
                ViewBag.updateError = "Create Failure";
                return View(um);
            }

            // ToDo: add persistent to DB.
            _usrs.Create(um);
            return View("Details", um);
        }
Add a view as in the previous steps, but set View content to Create.
Create View
Run the application, select the Create link, and add a new user. The Create method automatically takes advantage of client-side and server-side validation. Try to enter a user name that contains white space, such as "Ben X". When you tab out of the user name field, a client-side validation error (White space is not allowed) is displayed.

Add the Delete method

To complete the tutorial, add the following Delete method to the home controller:
public ViewResult Delete(string id) {
            return View(_usrs.GetUser(id));
        }

        [HttpPost]
        public RedirectToRouteResult Delete(string id, FormCollection collection) {
            _usrs.Remove(id);
            return RedirectToAction("Index");
        }
Add a Delete view as in the previous steps, setting View content to Delete.
Delete View

Understanding Models, Views, and Controllers (C#)

This tutorial provides you with a high-level overview of ASP.NET MVC models, views, and controllers. In other words, it explains the M', V', and C' in ASP.NET MVC.
After reading this tutorial, you should understand how the different parts of an ASP.NET MVC application work together. You should also understand how the architecture of an ASP.NET MVC application differs from an ASP.NET Web Forms application or Active Server Pages application.

The Sample ASP.NET MVC Application

The default Visual Studio template for creating ASP.NET MVC Web Applications includes an extremely simple sample application that can be used to understand the different parts of an ASP.NET MVC application. We take advantage of this simple application in this tutorial.
You create a new ASP.NET MVC application with the MVC template by launching Visual Studio 2008 and selecting the menu option File, New Project (see Figure 1). In the New Project dialog, select your favorite programming language under Project Types (Visual Basic or C#) and select ASP.NET MVC Web Application under Templates. Click the OK button.
Figure 01: New Project Dialog (Click to view full-size image)
When you create a new ASP.NET MVC application, the Create Unit Test Project dialog appears (see Figure 2). This dialog enables you to create a separate project in your solution for testing your ASP.NET MVC application. Select the option No, do not create a unit test project and click the OK button.
Figure 02: Create Unit Test Dialog (Click to view full-size image)
After the new ASP.NET MVC application is created. You will see several folders and files in the Solution Explorer window. In particular, you'll see three folders named Models, Views, and Controllers. As you might guess from the folder names, these folders contain the files for implementing models, views, and controllers.
If you expand the Controllers folder, you should see a file named AccountController.cs and a file named HomeController.cs. If you expand the Views folder, you should see three subfolders named Account, Home and Shared. If you expand the Home folder, you'll see two additional files named About.aspx and Index.aspx (see Figure 3). These files make up the sample application included with the default ASP.NET MVC template.
Figure 03: The Solution Explorer Window (Click to view full-size image)
You can run the sample application by selecting the menu option Debug, Start Debugging. Alternatively, you can press the F5 key.
When you first run an ASP.NET application, the dialog in Figure 4 appears that recommends that you enable debug mode. Click the OK button and the application will run.
Figure 04: Debugging Not Enabled dialog (Click to view full-size image)
When you run an ASP.NET MVC application, Visual Studio launches the application in your web browser. The sample application consists of only two pages: the Index page and the About page. When the application first starts, the Index page appears (see Figure 5). You can navigate to the About page by clicking the menu link at the top right of the application.
Figure 05: The Index Page (Click to view full-size image)
Notice the URLs in the address bar of your browser. For example, when you click the About menu link, the URL in the browser address bar changes to /Home/About.
If you close the browser window and return to Visual Studio, you won't be able to find a file with the path Home/About. The files don't exist. How is this possible?

A URL Does Not Equal a Page

When you build a traditional ASP.NET Web Forms application or an Active Server Pages application, there is a one-to-one correspondence between a URL and a page. If you request a page named SomePage.aspx from the server, then there had better be a page on disk named SomePage.aspx. If the SomePage.aspx file does not exist, you get an ugly 404 - Page Not Found error.
When building an ASP.NET MVC application, in contrast, there is no correspondence between the URL that you type into your browser's address bar and the files that you find in your application. In an ASP.NET MVC application, a URL corresponds to a controller action instead of a page on disk.
In a traditional ASP.NET or ASP application, browser requests are mapped to pages. In an ASP.NET MVC application, in contrast, browser requests are mapped to controller actions. An ASP.NET Web Forms application is content-centric. An ASP.NET MVC application, in contrast, is application logic centric.

Understanding ASP.NET Routing

A browser request gets mapped to a controller action through a feature of the ASP.NET framework called ASP.NET Routing. ASP.NET Routing is used by the ASP.NET MVC framework to route incoming requests to controller actions.
ASP.NET Routing uses a route table to handle incoming requests. This route table is created when your web application first starts. The route table is setup in the Global.asax file. The default MVC Global.asax file is contained in Listing 1.
Listing 1 - Global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication1
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                "Default",                                              // Route name
                "{controller}/{action}/{id}",                           // URL with parameters
                new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
            );

        }

        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);
        }
    }
}
When an ASP.NET application first starts, the Application_Start() method is called. In Listing 1, this method calls the RegisterRoutes() method and the RegisterRoutes() method creates the default route table.
The default route table consists of one route. This default route breaks all incoming requests into three segments (a URL segment is anything between forward slashes). The first segment is mapped to a controller name, the second segment is mapped to an action name, and the final segment is mapped to a parameter passed to the action named Id.
For example, consider the following URL:
/Product/Details/3
This URL is parsed into three parameters like this:
Controller = Product
Action = Details
Id = 3
The Default route defined in the Global.asax file includes default values for all three parameters. The default Controller is Home, the default Action is Index, and the default Id is an empty string. With these defaults in mind, consider how the following URL is parsed:
/Employee
This URL is parsed into three parameters like this:
Controller = Employee
Action = Index
Id = ��
Finally, if you open an ASP.NET MVC Application without supplying any URL (for example, http://localhost) then the URL is parsed like this:
Controller = Home
Action = Index
Id = ��
The request is routed to the Index() action on the HomeController class.

Understanding Controllers

A controller is responsible for controlling the way that a user interacts with an MVC application. A controller contains the flow control logic for an ASP.NET MVC application. A controller determines what response to send back to a user when a user makes a browser request.
A controller is just a class (for example, a Visual Basic or C# class). The sample ASP.NET MVC application includes a controller named HomeController.cs located in the Controllers folder. The content of the HomeController.cs file is reproduced in Listing 2.
Listing 2 - HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication1.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            ViewData["Title"] = "Home Page";
            ViewData["Message"] = "Welcome to ASP.NET MVC!";

            return View();
        }

        public ActionResult About()
        {
            ViewData["Title"] = "About Page";

            return View();
        }
    }
}
Notice that the HomeController has two methods named Index() and About(). These two methods correspond to the two actions exposed by the controller. The URL /Home/Index invokes the HomeController.Index() method and the URL /Home/About invokes the HomeController.About() method.
Any public method in a controller is exposed as a controller action. You need to be careful about this. This means that any public method contained in a controller can be invoked by anyone with access to the Internet by entering the right URL into a browser.

Understanding Views

The two controller actions exposed by the HomeController class, Index() and About(), both return a view. A view contains the HTML markup and content that is sent to the browser. A view is the equivalent of a page when working with an ASP.NET MVC application.
You must create your views in the right location. The HomeController.Index() action returns a view located at the following path:
\Views\Home\Index.aspx
The HomeController.About() action returns a view located at the following path:
\Views\Home\About.aspx
In general, if you want to return a view for a controller action, then you need to create a subfolder in the Views folder with the same name as your controller. Within the subfolder, you must create an .aspx file with the same name as the controller action.
The file in Listing 3 contains the About.aspx view.
Listing 3 - About.aspx
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server">
    <h2>About</h2>
    <p>
        Put content here.
    </p>
</asp:Content>
If you ignore the first line in Listing 3, most of the rest of the view consists of standard HTML. You can modify the contents of the view by entering any HTML that you want here.
A view is very similar to a page in Active Server Pages or ASP.NET Web Forms. A view can contain HTML content and scripts. You can write the scripts in your favorite .NET programming language (for example, C# or Visual Basic .NET). You use scripts to display dynamic content such as database data.

Understanding Models

We have discussed controllers and we have discussed views. The last topic that we need to discuss is models. What is an MVC model?
An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.
A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.
In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

Summary

This tutorial provided you with a high level overview of the different parts of an ASP.NET MVC web application. You learned how ASP.NET Routing maps incoming browser requests to particular controller actions. You learned how controllers orchestrate how views are returned to the browser. Finally, you learned how models contain application business, validation, and database access logic.

Understanding the ASP.NET MVC Execution Process


Requests to an ASP.NET MVC-based Web application first pass through the UrlRoutingModule object, which is an HTTP module. This module parses the request and performs route selection. The UrlRoutingModule object selects the first route object that matches the current request. (A route object is a class that implements RouteBase, and is typically an instance of the Route class.) If no routes match, the UrlRoutingModule object does nothing and lets the request fall back to the regular ASP.NET or IIS request processing.

From the selected Route object, the UrlRoutingModule object obtains the IRouteHandler object that is associated with the Route object. Typically, in an MVC application, this will be an instance of MvcRouteHandler. The IRouteHandler instance creates an IHttpHandler object and passes it the IHttpContext object. By default, the IHttpHandler instance for MVC is the MvcHandler object. The MvcHandler object then selects the controller that will ultimately handle the request.


Note:
When an ASP.NET MVC Web application runs in IIS 7.0, no file name extension is required for MVC projects. However, in IIS 6.0, the handler requires that you map the .mvc file name extension to the ASP.NET ISAPI DLL.

The module and handler are the entry points to the ASP.NET MVC framework. They perform the following actions:
  • Select the appropriate controller in an MVC Web application.
  • Obtain a specific controller instance.
  • Call the controller s Execute method.

The following table lists the stages of execution for an MVC Web project.

Stage Details
Receive first request for the application In the Global.asax file, Route objects are added to the RouteTable object.
Perform routing The UrlRoutingModule module uses the first matching Route object in the RouteTable collection to create the RouteData object, which it then uses to create a RequestContext (IHttpContext) object.
Create MVC request handler The MvcRouteHandler object creates an instance of the MvcHandler class and passes it the RequestContext instance.
Create controller The MvcHandler object uses the RequestContext instance to identify the IControllerFactory object (typically an instance of the DefaultControllerFactory class) to create the controller instance with.
Execute controller The MvcHandler instance calls the controller s Execute method.
Invoke action Most controllers inherit from the Controller base class. For controllers that do so, the ControllerActionInvoker object that is associated with the controller determines which action method of the controller class to call, and then calls that method.
Execute result A typical action method might receive user input, prepare the appropriate response data, and then execute the result by returning a result type. The built-in result types that can be executed include the following: ViewResult (which renders a view and is the most-often used result type), RedirectToRouteResult, RedirectResult, ContentResult, JsonResult, and EmptyResult.

ASP.NET MVC Overview

The Model-View-Controller (MVC) architectural pattern separates an application into three main components: the model, the view, and the controller. The ASP.NET MVC framework is a lightweight, highly testable presentation framework that (as with Web Forms-based applications) is integrated with existing ASP.NET features, such as master pages and membership-based authentication. The MVC framework is defined in the System.Web.Mvc namespace and is a fundamental, supported part of the System.Web namespace.

MVC is a standard design pattern. Some types of Web applications will benefit from the MVC framework. Others will continue to use the traditional ASP.NET application pattern that is based on Web Forms and postbacks. Other types of Web applications will combine the two approaches; neither approach excludes the other.

The MVC framework includes the following components:
Figure 01: Invoking a controller action that expects a parameter value (Click to view full-size image)
  • Models. Model objects are the parts of the application that implement the logic for the application s data domain. Often, model objects retrieve and store model state in a database. For example, a Product object might retrieve information from a database, operate on it, and then write updated information back to a Products table in SQL Server.

In small applications, the model is often a conceptual separation instead of a physical one. For example, if the application only reads a data set and sends it to the view, the application does not have a physical model layer and associated classes. In that case, the data set takes on the role of a model object.
  • Views. Views are the components that display the application s user interface (UI). Typically, this UI is created from the model data. An example would be an edit view of a Products table that displays text boxes, drop-down lists, and check boxes based on the current state of a Products object.

  • Controllers. Controllers are the components that handle user interaction, work with the model, and ultimately select a view to render that displays UI. In an MVC application, the view only displays information; the controller handles and responds to user input and interaction. For example, the controller handles query-string values, and passes these values to the model, which in turn queries the database by using the values.

The MVC pattern helps you create applications that separate the different aspects of the application (input logic, business logic, and UI logic). The UI logic belongs in the view. Input logic belongs in the controller. Business logic belongs in the model. This separation helps you manage complexity when you build an application, because it enables you to focus on one aspect of the implementation at a time. For example, you can focus on the view without depending on the business logic.

In addition to managing complexity,
-The MVC pattern makes it easier to test applications than it is to test a Web Forms-based ASP.NET Web application. For example, in a Web Forms-based ASP.NET Web application.
-A single class is used both to display output and to respond to user input.
-Writing automated tests for Web Forms-based ASP.NET applications can be complex, because to test an individual page, you must instantiate the page class, all its child controls, and additional dependent classes in the application.
-Because so many classes are instantiated to run the page, it can be hard to write tests that focus exclusively on individual parts of the application.
-Tests for Web Forms-based ASP.NET applications can therefore be more difficult to implement than tests in an MVC application.
-Moreover, tests in a Web Forms-based ASP.NET application require a Web server. The MVC framework decouples the components and makes heavy use of interfaces, which makes it possible to test individual components in isolation from the rest of the framework.

The loose coupling between the three main components of an MVC application also promotes parallel development. For instance, one developer can work on the view, a second developer can work on the controller logic, and a third developer can focus on the business logic in the model.

Deciding When to Create an MVC Application

You must consider carefully whether to implement a Web application by using either the ASP.NET MVC framework or the ASP.NET Web Forms model. The MVC framework does not replace the Web Forms model; you can use either framework for Web applications. (If you have existing Web Forms-based applications, these continue to work exactly as they always have.)

Before you decide to use the MVC framework or the Web Forms model for a specific Web site, weigh the advantages of each approach.

Advantages of an MVC-Based Web Application

The ASP.NET MVC framework offers the following advantages:
  • It makes it easier to manage complexity by dividing an application into the model, the view, and the controller.
  • It does not use view state or server-based forms. This makes the MVC framework ideal for developers who want full control over the behavior of an application.
  • It uses a Front Controller pattern that processes Web application requests through a single controller. This enables you to design an application that supports a rich routing infrastructure. For more information, see Front Controller on the MSDN Web site.
  • It provides better support for test-driven development (TDD).
  • It works well for Web applications that are supported by large teams of developers and Web designers who need a high degree of control over the application behavior.

Advantages of a Web Forms-Based Web Application

The Web Forms-based framework offers the following advantages:
  • It supports an event model that preserves state over HTTP, which benefits line-of-business Web application development. The Web Forms-based application provides dozens of events that are supported in hundreds of server controls.
  • It uses a Page Controller pattern that adds functionality to individual pages. For more information, see Page Controller on the MSDN Web site.
  • It uses view state or server-based forms, which can make managing state information easier.
  • It works well for small teams of Web developers and designers who want to take advantage of the large number of components available for rapid application development.
  • In general, it is less complex for application development, because the components (the Page class, controls, and so on) are tightly integrated and usually require less code than the MVC model.

Features of the ASP.NET MVC Framework

The ASP.NET MVC framework provides the following features:
  • Separation of application tasks (input logic, business logic, and UI logic), testability, and test-driven development (TDD) by default. All core contracts in the MVC framework are interface-based and can be tested by using mock objects, which are simulated objects that imitate the behavior of actual objects in the application. You can unit-test the application without having to run the controllers in an ASP.NET process, which makes unit testing fast and flexible. You can use any unit-testing framework that is compatible with the .NET Framework.
  • An extensible and pluggable framework. The components of the ASP.NET MVC framework are designed so that they can be easily replaced or customized. You can plug in your own view engine, URL routing policy, action-method parameter serialization, and other components. The ASP.NET MVC framework also supports the use of Dependency Injection (DI) and Inversion of Control (IOC) container models. DI allows you to inject objects into a class, instead of relying on the class to create the object itself. IOC specifies that if an object requires another object, the first objects should get the second object from an outside source such as a configuration file. This makes testing easier.
  • A powerful URL-mapping component that lets you build applications that have comprehensible and searchable URLs. URLs do not have to include file-name extensions, and are designed to support URL naming patterns that work well for search engine optimization (SEO) and representational state transfer (REST) addressing.
  • Support for using the markup in existing ASP.NET page (.aspx files), user control (.ascx files), and master page (.master files) markup files as view templates. You can use existing ASP.NET features with the ASP.NET MVC framework, such as nested master pages, in-line expressions (<%= %>), declarative server controls, templates, data-binding, localization, and so on.
  • Support for existing ASP.NET features. ASP.NET MVC lets you use features such as forms authentication and Windows authentication, URL authorization, membership and roles, output and data caching, session and profile state management, health monitoring, the configuration system, and the provider architecture.