ASP.NET MVC GRID part 1
November 27, 2008
Background:-
Today we will start by making a simple grid. Rather than just creating a Grid out of the <table> tag. Why not utilize the Grid control that all of the pre-MVC programmers have been familiar with: GridView. Before we began, allow me to explain little bit about MVC Frame Work. For those who are “Experts” can skip this portion and jump right to the Action section, or you can stick around and read this section as well because wisdom lies in knowing the fundamentals.
- MVC:- Stands for Model – View – Controller.
- MODELs :- Just bunch of Class files that are responsible for maintaining state.
- VIEWs :- Consists of all of the Web Pages such as aspx, ascx, etc. You can also inherit off the model data to generate the View.
- CONTROLLER: – Think of controller as the action handler.
i.e User clicks on a link and controller intercepts that event (action). Also, within the Controller you can manipulate the Model.
Lets dissect the CONTROLLER bit more because usually thats what confuses the new MVC programmers the most.
Controller handles 6 different action types:-
- ViewResult:- Represent HTML & Markup [ most common ]
- EmptyResults:- Represent no results.
- RedirectResult:- Redirects to a new URL.
- RedirectToRouteResult:- Redirects to a new Controller action.
- JsonResult:- Represent json formatted result.
- ContentResult:- Represent text result.
** All of these action types inherits from the ActionResults base class which is the default return type. **
To actually return these action types, you must use the following predefined methods.
- View():- Returns ViewResult action result.
- Redirect():- Returns RedirectResult action.
- RedirectToAction():- Returns RedirectToRouteResult action.
- RedirectToRoute():- Returns RedirectToRouteResult action.
- Json():- Returns Json results.
- Content():- Returns ContentResult.
For example:- HomeController.cs
public ActionResult Get()
{
return View();
}
or you can also specify a different View such as:
public ActionResult Get()
{
return View("Foo");
}
** Name of the folder must match with the name of the Controller, so the MVC Frame Work will know where to find the View.**
How to pass data from Controller to the View?
When Controller is invoked, it returns “view specific data”, hence ViewData. Think of ViewData dictionary property of ASP.NET MVC Frame Work as the content that get returned from Controller. The content can be a Web Page as I mentioned earlier or even Custom Objects (you will see an example of this later).
How do I access ViewData within a Web Page?
When you add a Web Page (view) to the project with the appropriate directory ofcourse, you will notice that the page will be derived from “ViewPage” class. Compared to before in regular ASP.NET where a Web Page (Web Form) derived from “System.Web.UI. Page” class.
In ASP.NET MVC, “System.Web.Mvc.ViewPage” is a subclass of the existing “System.Web.UI. Page” class. ViewPage class will give us the access to the ViewData dictionary property that we can use to access the content that was returned from the Controller. Naturally, this is simple concept to grasp after understanding core concept, isn’t that right?
How do I render the content of ViewData onto the Web Page?
Depends on the content, if it is just a string value or even an HTML markup.
- You can use: <%= Some Code %> :- Represents Response.Write();
- On the other hand, you can use: <% Some Code %> :- Allows you implement any compilable code either of C# or VB.NET.
This ends our background section.
Action:-
Finally, we will built a simple but functional Grid and in the upcoming series we will expand on this using jQuery and Ajax to add more complex functionalities that will meet the real world demands.
Goal:-
When were are done, our final output will look the following:-

Start with blank ASP.NET MVC application, I’m using Visual Studio 2008 with MVC Beta.
File >> New Project >> ASP.NET MVC Application

After you have completed the create new project wizard, Visual Studio 2008 solution explorer should look like this:

Under Scripts folder, Visual Studio 2008 have added for us the necessary jQuery libraries that we need. Very cool… By the way, VS 2008 also give us the intelli-Sense for JavaScript and with the downloadable plug-in you can get intelli-Sense for jQuery as well.

Our Controller folder should look like this:

We are not interested in the AccountController.cs but we are mainly interested in HomeController.cs file.
HomeController.cs class should look like the following:-

When you run the project as it is, it should look like this:

Now lets add Models to our project, under the Models folder, add two new Classes called MVCGridModel.cs and GridEntity:


We will define our MVCGridModel.cs class little later, but for now lets define our GridEntity.cs class.
GridEntity.cs is our custom object class that we will use to bind our Grid. Properties IndexField and ValueField represents our columns in our Grid.

Now lets define the MVCGridModel, which you will soon realize is very straight forward:
Our main ingredient in our model is the GridView which we will inherit from System.Web.UI.WebControls class.
First, create a new public method called GetResults which will return a string, you will see why later.
public string GetResults()
{
//create dynamic grid here
}
GridView gv = new GridView();
Since, we don’t need to display the footer, we can just set it to false.
gv.ShowFooter = false;
I usually set the width to 100%, so that the Grid can expand and shrink automatically when the user resize the browser.
gv.Width = Unit.Percentage(100);
GridView exposes AutoGenerateColumns attribute, which is set to true by default. The purpose of this attribute is to render all data fields that it can AS THEY ARE and by setting it to false, we can control how our columns will be displayed.
gv.AutoGenerateColumns = false;
There is a cool attribute that GridView provide is called RenderControl. RenderControl attribute is probably one of the least used attribute by the .NET programmers, therefore not many of them are aware of the awesome functionality it has. The main function of this attribute is the render entire GridView in pure HTML. It is kind of like similar to building the Grid manually out of the <Table> tags. So, why not take advantage of this “badass” feature.
To use RenderControl attribute we need to bring in two other key players: StringWriter & HtmlTextWriter.
- RenderControl attribute outputs the content to HtmlTextWriter object.
- HtmlTextWriter outputs the markup content to StringWriter stream.
using (StringWriter sw = new StringWriter())
{
HtmlTextWriter hw = new HtmlTextWriter(sw);
gv.RenderControl(hw);
hw.Flush();
string gridMarkUp = hw.InnerWriter.ToString();
}
We need a collection of object that we can use to bind our Grid’s DataSource. Best way we can do that is to use our GridEntity object that we created earlier and create a Collection List.
private List<GridEntity> GetData()
{
//Instantiate our GridEntity object as a new List Collection
List<GridEntity> lst = new List<GridEntity>();
GridEntity obj; //Instantiate GridEntity object
obj = new GridEntity();
obj.IndexField = 1; //Represent the Primary Key of the DataBase table.
obj.ValueField = "Column one"; //Represent column field.
lst.Add(obj); //append Custom object to the Collection.
//Repeat above process to create as many Rows you want
obj = new GridEntity();
obj.IndexField = 2;
obj.ValueField = "Column two";
lst.Add(obj);
return lst; // Return our Collection List
}
public class MVCGridModel
{
public MVCGridModel()
{
}
public string GetResults()
{
string gridMarkUp = string.Empty;
GridView gv = new GridView();
gv.ShowFooter = false;
gv.Width = Unit.Percentage(100);
gv.AutoGenerateColumns = false;
BoundField col;
col = new BoundField();
col.DataField = "IndexField";
col.HeaderText = "Perimary Field";
gv.Columns.Add(col);
col = new BoundField();
col.DataField = "ValueField";
col.HeaderText = "Value Field";
gv.Columns.Add(col);
gv.DataSource = GetData();
gv.DataBind();
using (StringWriter sw = new StringWriter())
{
HtmlTextWriter hw = new HtmlTextWriter(sw);
gv.RenderControl(hw);
hw.Flush();
gridMarkUp = hw.InnerWriter.ToString();
}
return gridMarkUp;
}
private List<GridEntity> GetData()
{
List<GridEntity> lst = new List<GridEntity>();
GridEntity obj;
obj = new GridEntity();
obj.IndexField = 1;
obj.ValueField = "Column one";
lst.Add(obj);
obj = new GridEntity();
obj.IndexField = 2;
obj.ValueField = "Column two";
lst.Add(obj);
return lst;
}
}
First, we will create the action in our Home controller and than use the built-in option in VS 2008 to add a new View to the project. Cool…..
create a new action:
public ActionResult GetGrid()
{
//var type is the implicit variable type declartion.
var model = new MVCGridModel();
return View(model);
}
example:
var i = 5;
// Represents an integer type.
var j = “This a string”;
// Represents a string type variable.
Here is the complete code of our Home Controller:
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();
}
public ActionResult GetGrid()
{
//var type is the implicit variable type declartion.
var model = new MVCGridModel();
return View(model);
}
}
When you Right-Click within our GetGrid() action, VS 2008 will provide you with “Add View” option that is now part of the context menu.

When you select Add View, you will get the following window:

Couple of things are happening here:
- View name: This will be automatically populated for you because as we talked about this earlier, the action name and View has to be the same.
- First check box: Here you have the option to utilized the Model or another other custom objects that your view can inherit.
- Second check box: Very straight forward, this tell whether you want your View to be part of the master page or not. In our case we want this view to be part of the master page.
When you hit add, your view will be automatically added to the appropriate folder:

the HTML code of our View should look like this:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="GetGrid.aspx.cs" Inherits="MVCGridApp.Views.Home.GetGrid" %> <asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server"> </asp:Content>
namespace MVCGridApp.Views.Home
{
public partial class GetGrid : ViewPage<MVCGridModel>
{
}
}
Now, we will add something in our code behind that will give us little bit advantage. I like to add a public property that will return the ViewData.
public partial class GetGrid : ViewPage<MVCGridModel>
{
//public property makes it lot easier for typing.
//Instead of doing ViewData.Model, I can just do Model.something. Handy little trick to keep
//things simple as possbile.
public MVCGridModel Model
{
get { return ViewData.Model; }
}
}
<div id=”gvContent”><%= Model.GetResults() %></div>
If you remember back in our MVCGridModel we had created a GetResults() method that returns the HTML markup string of the GridView control. So by doing <%= Model.GetResults() %> within the div tag, our entire Grid will be embedded in the div. You will see the advantage of this when we apply the CSS styles to it.
This is the complete HML code of our View:
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<style type="text/css">
#gvContent table
{
border: 1px solid black;
}
#gvContent th
{
border: 1px solid #000000;
}
#gvContent td
{
border: 1px solid #000000;
}
#gvContent tr
{
border: 1px solid #000000;
}
</style>
<div id="gvContent"></div>
There are many ways to built a Grid and this happens to be one of them.