Introduction
The ASP.NET MVC Framework allows building a Web application
as a composition of three roles: Model, View, and Controller. The View role can be implemented in several ways. The popular view engines used in the ASP.NET
MVC 3 Framework are the Razor
View Engine and the Web Forms (ASPX) view engine. Other than that a
View can be implemented by accessing Controller
methods using jQuery. This article illustrates all these ways of implementation of Views in
an MVC application.
Creating the MVC application
First let’s create an MVC application and develop the Model and Controller parts. Create an empty MVC3 application.
Set the “View engine” as ASPX.
A project with the following folder structure will be created:
Creating the Model part
In order to create the Model, add the following class under the “Model” folder:
Product.cs
public class Product
{
public string ProductID { get; set; }
public string ProductName { get; set; }
public int Quantity { get; set; }
public decimal Price { get; set; }
}
Implementing the Controller Method
In order to create a Controller method, right click on the “Controller” folder, then select Add - >Controller.
Name the Controller as ProductController
.
The ProductController
contains an action method Index
as follows:
public class ProductController : Controller
{
public ActionResult Index()
{
return View();
}
}
The method returns an ActionResult
. Every method in a controller class returns an
ActionResult
by default. An ActionResult
is a return type of a controller
method, also called an action method. ActionResult
encapsulates the result of an action method and is used to perform a framework level operation
on behalf of the action method.
Let’s modify the action method in order to return a list of Product
s using the Product model:
public ActionResult ProductList()
{
List<Product> productLst = new List<Product>{
new Product{ProductID="P01",ProductName="Pen",Quantity=10,Price=12},
new Product{ProductID="P02",ProductName="Copy",Quantity=12,Price=20},
new Product{ProductID="P03",ProductName="Pencil",Quantity=15,Price=22},
new Product{ProductID="P04",ProductName="Eraser",Quantity=20,Price=27}
};
return View();
}
Once we are done with the Controller implementation, we are ready for routing the result to some view interface. Before that we need to
understand the routing construct of the MVC Framework.
Action methods, action results, and routing
Action methods and the routing system work together in every MVC application. MVC does this by using a set of conventions, defined as
routing patterns, in the global.asax.cs file. These patterns connect HTTP requests with controllers and action methods. As an HTTP Request enters the
routing system, it determines which controller should serve data to which view (if any).
global.asax.cs defines the default routing pattern, {controller}/{action}/{id}, as follows:
routes.MapRoute(
"Default", "{controller}/{action}/{id}",
In our example, the controller name is “Product
” and the action name is “ProductList
”. Our controller or action method doesn’t have
any parameters. So the URL for routing the result should be “Product/ProductList”.
Approach 1 - Implementing a View using the ASPX engine
As we are done with the Model and Controller implementation, now it’s time to implement the View. Build the project. Right
click in the Controller method and select “Add View”:
Let the View name be “ProductView
”. Check “Create a strongly-typed view”. Select the model as
Product
from the View data class dropdown. Don’t forget to
build the project before adding the View. Otherwise the View data classes would not be populated.
Select “View Engine” as ASPX(C#). Select “View Content” as “List”.
Through this screen, the ASP.NET MVC Framework helps us to implement the classic MVC design pattern in our application. We are passing the model as
the “View data
class” for the relevant view. Besides, we are getting the scope to selecting a “View Engine” in order to render the result returned by the Controller method.
In addition to that we can mention the representation structure for the View (List, Detail, etc.) in the “View content” section.
Click “Add” in order to add the View.
A new folder will be created with the controller name (Product
), and the View file (“ProductView.aspx”) will be added in the same.
Modify the controller method in order to serve data to the newly created View “ProductView.aspx”.
public ActionResult ProductList()
{
List<Product> productLst = new List<Product>{
new Product{ProductID="P01",ProductName="Pen",Quantity=10,Price=12},
new Product{ProductID="P02",ProductName="Copy",Quantity=12,Price=20},
new Product{ProductID="P03",ProductName="Pencil",Quantity=15,Price=22},
new Product{ProductID="P04",ProductName="Eraser",Quantity=20,Price=27}
};
return View("ProductView", productLst);
}
Open the View file “ProductView.aspx”. As we have given the responsibility for rendering View to the ASPX engine, the layout has been developed using
ASP.NET’s existing .ASPX markup syntax, using <%= %>
blocks:
Now that we are done with the View implementation, it’s time to develop an anchor page and access the View through its routing logic. Create an “aspx” page named
“default.aspx” under root and access the View through it. This page needs to be handled in a different way than normal ASPX pages. In order to achieve
MVC Framework behavior, the page is required to be handled by a special HttpHandler MvcHttpHandler
.
Add the following code in the load event of the page:
public partial class _Default : Page
{
public void Page_Load(object sender, System.EventArgs e)
{
HttpContext.Current.RewritePath(Request.ApplicationPath);
IHttpHandler httpHandler = new MvcHttpHandler();
httpHandler.ProcessRequest(HttpContext.Current);
}
}
As per the routing pattern defined in Global.asax ("{controller}/{action}/{id}"), the routing
URL
for the Product view page would be “Product/ProductList”.
Add a link in the default.aspx page in order to access the View using its routing construct as follows:
Also inherit the page from the “System.Web.Mvc.ViewPage
” namespace.
Set “default.aspx” as the startup page and run the application.
Click the link in order to view the product list rendered by the ASPX View engine.
Approach 2 - Implementing a View using the Razor engine
In the above section, we implemented the View role of our MVC application using
the ASPX View engine. Now we will implement the View role of the
application using the Razor View engine.
Let’s create one more model Supplier
:
Supplier.cs
public class Supplier
{
public string SupplierID { get; set; }
public string SupplierName { get; set; }
public string SupplierAddress { get; set; }
}
In order to create a Controller method, right click on the “Controller” folder, then select Add - >Controller. Name the controller as
SupplierController
.
Let’s modify the action method in order to return a list of Suppliers using the Supplier model:
public ActionResult SupplierList()
{
List<Supplier> supplierList = new List<Supplier>{
new Supplier{SupplierID="S01", SupplierName="Kausik",SupplierAddress="Kolkata"},
new Supplier{SupplierID="S02", SupplierName="Sandeep",SupplierAddress="Delhi"},
new Supplier{SupplierID="S03", SupplierName="Soumick",SupplierAddress="Chennai"},
new Supplier{SupplierID="S04", SupplierName="Arindam",SupplierAddress="Mumbai"}
};
return View();
}
As we are done with the Model and Controller implementation, now it’s time to implement the View. Build the project. Right
click in the Controller method and select “Add View”:
Let the View name be “SupplierView
”. Check “Create a strongly-typed view”. Select the model as Supplier from the View data class dropdown.
Select “View Engine” as Razor(CSHTML). Select “View Content” as “List”.
Here we are getting the scope to select a different “View Engine” other than ASPX in order to render the result returned by the Controller method. As we have
chosen the Razor(CSHTML) engine, our View will be handled by the Razor View engine.
Click “Add” in order to add the View.
A new folder will be created with the controller name (Supplier) and the View
file (“SupplierView.cshtml”) will be added in the same. The View page is no more an
.aspx page but a .cshtml page.
Modify the controller method in order to serve data to the newly created View “SupplierView.aspx”.
public ActionResult SupplierList()
{
List<Supplier> supplierList = new List<Supplier>{
new Supplier{SupplierID="S01", SupplierName="Kausik",SupplierAddress="Kolkata"},
new Supplier{SupplierID="S02", SupplierName="Sandeep",SupplierAddress="Delhi"},
new Supplier{SupplierID="S03", SupplierName="Soumick",SupplierAddress="Chennai"},
new Supplier{SupplierID="S04", SupplierName="Arindam",SupplierAddress="Mumbai"}
};
return View("SupplierView", supplierList);
}
Open the View file “SupplierView.cshtml”. As we have given the responsibility for rendering
the View to the Razor engine, the layout has been developed using Razor’s markup syntax, using
a @ character. Unlike <% %>
code nuggets, Razor does not require you to explicitly close the code-block:
As per the routing pattern defined in Global.asax ("{controller}/{action}/{id}") the routing
URL for the Suppliers view page would be “Supplier/SupplierList”.s
Add a link in the default.aspx page in order to access the view using its routing construct as follows:
Set the “default.aspx” as the startup page and run the application.
Click the link in order to view the suppliers list rendered by the Razor View engine.
Approach 3 - Implementing a View using jQuery
In this section, we will implement the View role using jQuery. The View will be handled by
the ASPX engine, but we will not be using <% %>
code nuggets for manipulating
the representation. Rather, we will access the Controller method using a jQuery/Ajax call and manipulate the values returned by the Controller method in the front-end.
Let’s create one more model Order
:
Order.cs
public class Order
{
public string OrderID { get; set; }
public int OrderQty { get; set; }
public decimal OrderPrice { get; set; }
}
In
order to create a Controller method, right click on the “Controller” folder,
then select Add - >Controller. Name the controller as OrderController
.
Add a new action method GetOrderList
in the controller.
The
method will return a list of orders using the Order model. In this case we will
wrap the returned result into JSON format. Hence the return type of the
Controller method is JsonResult
. Also the Suppliers list object is being
passed into the Framework method Json
. The method serializes the list
object into JSON format.
public JsonResult GetOrderList()
{
List<Order> OrderLst = new List<Order>{
new Order{ OrderID="101", OrderQty=10, OrderPrice=12},
new Order{ OrderID="201", OrderQty=12, OrderPrice=15},
new Order{ OrderID="301", OrderQty=15, OrderPrice=17}
};
return Json(OrderLst, JsonRequestBehavior.AllowGet);
}
Right
click in the Controller method and select “Add View”. Set the View name as
“OrderView”. Un-check “Create a strongly-typed view”.
Select
“View Engine” as ASPX(C#). Set “View Content” as “Empty”.
In
the earlier implementations, we had passed a specific model to the View and
made our View strongly typed. But here we will access the Controller method
using an AJAX call from jQuery. So we are not required to pass any model.
Also,
in the earlier implementations we had selected “View content” as “List”.
Actually, we had selected a representation format and allowed ASPX or the Razor
View engine to manipulate the presentation layer with their native syntax (<%
%> or @). But here we will implement the presentation layer manually using
simple HTML.
A
new folder will be created with the controller name (Order), and the View file
(“OrderView.aspx”) will be added in the same.
Modify
the controller method in order to serve data to the newly created View “OrderView.aspx”.
public ActionResult OrderList()
{
return View("OrderView");
}
Now,
in order to call the controller method GetOrderList
, we need to initiate
an AJAX call from the “OrderView.aspx” page. We will implement the AJAX call
using jQuery. First include the jQuery library. The “Script” folder in the
project consists of the jQuery library. Include the path of the “Script” folder in
order to get access to the jQuery library:
<script type="text/javascript" src="../../Scripts/jquery-1.4.1.js">
The
Controller method GetOrderList
will return the list of orders in JSON
format. We are required to parse the values from JSON and represent it using
an HTML table. For this we need to write a function using jQuery. Let’s write a
function CreateHTMLTableFromJSON
in a separate
script file JQScript.js under the “Script” folder. Also, include the script
file in the “OrderView.aspx” page.
<script type="text/javascript" src="../../Scripts/JQScript.js">
</script>
Now
initiate the AJAX call as follows:
In
the above code the Controller method GetOrderList
is being called by
the jQuery AJAX call. The JSON response returned by the method is being parsed to an
HTML table, by the client side function CreateHTMLTableFromJSON
written in
jQuery. At the end, the
HTML table is appended to a “div
” named “OrderGrid
”.
As
per the routing pattern defined in Global.asax ("{controller}/{action}/{id}"), the routing
URL
for the Product view page would be “Order/OrderList”.
The
default.aspx page should have a link to access the View using its routing
construct as follows:
Set
“default.aspx” as the startup page and run the application.
Click
the link in order to view the orders list fetched using jQuery:
Sometimes in Internet Explorer, a few consecutive
refreshes are required for getting results from the jQuery AJAX call. In this case, please
try Firefox.
I
have tried to explore three different approaches for implementing the View role
in an MVC application. A specific approach between these should be adopted in
order to develop a robust View in the application.