Beginner's Guide to Create GridView in ASP.Net MVC 5

In this post, we will be seeing how we can create a GridView in ASP.NET MVC, like we have in ASP.NET web form. There are many third party plugins, written in jQuery available for both server side and client side. These plugins provide all the essential functionality that we have in web forms, including searching, sorting, and paging etc. It totally depends on the requirements of the specific application if the search is needed at client side or server side.
You can download the source code from this link. Some of the libraries and plugins are:
These all have their pros and cons, but personally, I have found jQuery datatables to be a good choice. It is highly flexible. It supports pagination, instant-search, and multi-column ordering. It also supports almost all the data sources to which it can be bound. Some of them are:
One of the best options I like in it is that it supports both client side searching, pagination, sorting etc, but it also provides the option to have server side processing, as there can be a case where we have too much data in database. In that case, the client side paging wouldn’t be a good option. Just think, millions of rows in a table and if they are bound to it using client side pagination, it will make our page unresponsive due to a high amount of rows processing and html rendering.
We will first see an example of how we can implement it, using client side processing. So, let’s get started. We will have a working Grid with searching, sorting, and paging at the end of the post, which will look like:
First of all, create a database and table that we will be using in this post. Open SQL Management Studio and run the following script:
  1. CREATE DATABASE [GridExampleMVC]    
  2. GO    
  3. CREATE TABLE [dbo].[Assets] (    
  4.     [AssetID]                   UNIQUEIDENTIFIER NOT NULL,    
  5.     [Barcode]                   NVARCHAR (MAX)   NULL,    
  6.     [SerialNumber]              NVARCHAR (MAX)   NULL,    
  7.     [FacilitySite]              NVARCHAR (MAX)   NULL,    
  8.     [PMGuide]                   NVARCHAR (MAX)   NULL,    
  9.     [AstID]                     NVARCHAR (MAX)   NOT NULL,    
  10.     [ChildAsset]                NVARCHAR (MAX)   NULL,    
  11.     [GeneralAssetDescription]   NVARCHAR (MAX)   NULL,    
  12.     [SecondaryAssetDescription] NVARCHAR (MAX)   NULL,    
  13.     [Quantity]                  INT              NOT NULL,    
  14.     [Manufacturer]              NVARCHAR (MAX)   NULL,    
  15.     [ModelNumber]               NVARCHAR (MAX)   NULL,    
  16.     [Building]                  NVARCHAR (MAX)   NULL,    
  17.     [Floor]                     NVARCHAR (MAX)   NULL,    
  18.     [Corridor]                  NVARCHAR (MAX)   NULL,    
  19.     [RoomNo]                    NVARCHAR (MAX)   NULL,    
  20.     [MERNo]                     NVARCHAR (MAX)   NULL,    
  21.     [EquipSystem]               NVARCHAR (MAX)   NULL,    
  22.     [Comments]                  NVARCHAR (MAX)   NULL,    
  23.     [Issued]                    BIT              NOT NULL,    
  24.     CONSTRAINT [PK_dbo.Assets] PRIMARY KEY CLUSTERED ([AssetID] ASC)    
  25. )    
  26. GO  
The complete SQL script file is attached in the source code. So, you can use it to create the database and table with sample data.
Now, create a new ASP.NET MVC 5 web application. Open Visual Studio 2015. Go to File >> New >> Project.
From the dialog, navigate to the Web and select ASP.NET Web Application project and click OK.
From Templates, select MVC. Check the unit tests if you are writing the unit tests as well, for your implementations. Click OK.
Our project is created with basic things in place for us. Now, we will start by creating the database context class because we will be using Entity Framework for the Data Access.
First of all, we need to create Model for the Asset table which we will be used for retrieving the data, using ORM.
In Model folder, create a new class named as Asset:
  1. using System.ComponentModel.DataAnnotations;  
  3. namespace GridExampleMVC.Models  
  4. {  
  5.     public class Asset  
  6.     {  
  7.         public System.Guid AssetID { getset; }  
  9.         [Display(Name = "Barcode")]  
  10.         public string Barcode { getset; }  
  12.         [Display(Name = "Serial-Number")]  
  13.         public string SerialNumber { getset; }  
  15.         [Display(Name = "Facility-Site")]  
  16.         public string FacilitySite { getset; }  
  18.         [Display(Name = "PM-Guide-ID")]  
  19.         public string PMGuide { getset; }  
  21.         [Required]  
  22.         [Display(Name = "Asset-ID")]  
  23.         public string AstID { getset; }  
  25.         [Display(Name = "Child-Asset")]  
  26.         public string ChildAsset { getset; }  
  28.         [Display(Name = "General-Asset-Description")]  
  29.         public string GeneralAssetDescription { getset; }  
  31.         [Display(Name = "Secondary-Asset-Description")]  
  32.         public string SecondaryAssetDescription { getset; }  
  33.         public int Quantity { getset; }  
  35.         [Display(Name = "Manufacturer")]  
  36.         public string Manufacturer { getset; }  
  38.         [Display(Name = "Model-Number")]  
  39.         public string ModelNumber { getset; }  
  41.         [Display(Name = "Main-Location (Building)")]  
  42.         public string Building { getset; }  
  44.         [Display(Name = "Sub-Location 1 (Floor)")]  
  45.         public string Floor { getset; }  
  47.         [Display(Name = "Sub-Location 2 (Corridor)")]  
  48.         public string Corridor { getset; }  
  50.         [Display(Name = "Sub-Location 3 (Room No)")]  
  51.         public string RoomNo { getset; }  
  53.         [Display(Name = "Sub-Location 4 (MER#)")]  
  54.         public string MERNo { getset; }  
  56.         [Display(Name = "Sub-Location 5 (Equip/System)")]  
  57.         public string EquipSystem { getset; }  
  59.         public string Comments { getset; }  
  61.         public bool Issued { getset; }  
  63.     }  
  64. }  
Now, Navigate to Models folder from Solution Explorer and open IdenityModels.cs file. We will add a property for the Asset table in the database context which will be the Entity Framework representation of Asset table that we created using the script. Add new property in the ApplicationDbContext class:
  1. public class ApplicationDbContext : IdentityDbContext<ApplicationUser>  
  2. {  
  3.     public ApplicationDbContext()  
  4.         : base("DefaultConnection", throwIfV1Schema: false)  
  5.     {  
  6.     }  
  8.     public DbSet<Asset> Assets { getset; }  
  10.     public static ApplicationDbContext Create()  
  11.     {  
  12.         return new ApplicationDbContext();  
  13.     }  
  14. }  
The above is the default Entity Framework settings for ASP.NET identity 2.0. We are extending it with our own tables, for which we have added new DbSet to Asset table.
Now, add an empty controller in Controllers folder, named as AssetController. We will be using this for all the Asset related work. Here is how it should look:
  1. public class AssetController : Controller  
  2. {  
  3.     // GET: Asset  
  4.     public ActionResult Index()  
  5.     {  
  6.         return View();  
  7.     }  
  8. }  
Now, we will install the jQuery datatables that we will be using to build the Grid. Go to Tools >> NuGet Package Manager >> Manage Nuget Packages for Solution and click it.
The package manager will get opened and by default it will be displaying the installed nuget packages in your solution. Click the browser button and then search for jQuery datatables package. Select it and check the projects of the solution in which you want to install this package. In our case, we are installing it in GridExampleMVC web project only as per requirement. Then, press the install button.
Visual Studio will prompt you to tell that it is going to modify the solution. You will have to press OK to continue the installation of the package.
After the nuget package is installed successfully, we need to include the necessary JS and CSS of jQuery datatables in the View where we will use it. For that, we have to register the jQuery datatables. Open the BundleConfig.cs file located in App_Start folder and add the following code for CSS and JS files, at the end:
  1. bundles.Add(new ScriptBundle("~/bundles/datatables").Include(  
  2. "~/Scripts/DataTables/jquery.dataTables.min.js",  
  3. "~/Scripts/DataTables/dataTables.bootstrap.js"));  
  5. bundles.Add(new StyleBundle("~/Content/datatables").Include(  
  6. "~/Content/DataTables/css/dataTables.bootstrap.css"));  
After registering the scripts and style for datatables, we need to add them in our master layout which is by default _Layout.cshtml located in Views >> Shared as defined in the _ViewStart.cshtml, located in the same location.
Before writing the controller code, we need to configure the connection string for Entity Framework that will be used to connect databases when it will be doing database operations i.e. running queries. So, our connection string should be pointing to a valid data source, so that our application won’t break when we run it.
For that, open web.config and provide the connection string for the database. In config file, you will find the  connectionStrings under configurations node. You will need to modify the connection string in that node according to your system. In my case, it looks like:
  1. <connectionStrings>  
  2.     <add name="DefaultConnection" connectionString="Data Source=(localdb)\MSSQLLocalDB;Initial Catalog=GridExampleMVC;Integrated Security=True;MultipleActiveResultSets=true" providerName="System.Data.SqlClient" />  
  3. </connectionStrings>  
Now, in controller, add a property for database context that we will be using for querying the database.
  1. private ApplicationDbContext _dbContext;  
  3. public ApplicationDbContext DbContext  
  4. {  
  5.     get  
  6.     {  
  7.         return _dbContext ?? HttpContext.GetOwinContext().Get<ApplicationDbContext>();  
  8.     }  
  9.     private set  
  10.     {  
  11.         _dbContext = value;  
  12.     }  
  14. }  
This property will be used to query the database with Entity Framework in all actions of the controller wherever needed.
Now, in the index action, we will simply fetch all the rows of the table and pass it to the View:
  1. public ActionResult Index()  
  2. {  
  3.     return View(DbContext.Assets.ToList());  
  4. }  
  6. Our complete controller class code now looks like:  
  7. using GridExampleMVC.Models;  
  8. using System.Linq;  
  9. using System.Web;  
  10. using System.Web.Mvc;  
  11. using Microsoft.AspNet.Identity.Owin;  
  14. namespace GridExampleMVC.Controllers  
  15. {  
  16.     public class AssetController : Controller  
  17.     {  
  19.         private ApplicationDbContext _dbContext;  
  21.         public ApplicationDbContext DbContext  
  22.         {  
  23.             get  
  24.             {  
  25.                 return _dbContext ?? HttpContext.GetOwinContext().Get<ApplicationDbContext>();  
  26.             }  
  27.             private set  
  28.             {  
  29.                 _dbContext = value;  
  30.             }  
  32.         }  
  34.         public AssetController()  
  35.         {  
  37.         }  
  39.         public AssetController(ApplicationDbContext dbContext)  
  40.         {  
  41.             _dbContext = dbContext;  
  42.         }  
  44.         // GET: Asset  
  45.         public ActionResult Index()  
  46.         {  
  47.             return View(DbContext.Assets.ToList());  
  48.         }  
  49.     }  
  50. }  
Here comes the View part now. Here, we will write the code about how it should render as html. So, create a View with Template Empty (Without Model) for the Index action and add the following code in it:
  1. @model IEnumerable< GridExampleMVC.Models.Asset>  
  3. <div class="row">  
  4.     <div class="col-md-12">  
  5.         <div class="panel panel-primary list-panel" id="list-panel">  
  6.             <div class="panel-heading list-panel-heading">  
  7.                 <h1 class="panel-title list-panel-title">Assets</h1>  
  8.             </div>  
  9.             <div class="panel-body">  
  10.                 <table id="assets-data-table" class="table table-striped table-bordered" style="width:100%">  
  11.                     <thead>  
  12.                         <tr>  
  13.                             <th>Bar Code</th>  
  14.                             <th>Manufacturer</th>  
  15.                             <th>Model Number</th>  
  16.                             <th>Building</th>  
  17.                             <th>Room No</th>  
  18.                             <th>Quantity</th>  
  19.                         </tr>  
  20.                     </thead>  
  21.                     <tbody>  
  22.                         @foreach (var asset in Model)  
  23.                         {  
  24.                             <tr>  
  25.                                 <td>@asset.Barcode</td>  
  26.                                 <td>@asset.Manufacturer</td>  
  27.                                 <td>@asset.ModelNumber</td>  
  28.                                 <td>@asset.Building</td>  
  29.                                 <td>@asset.RoomNo</td>  
  30.                                 <td>@asset.Quantity</td>  
  31.                             </tr>  
  32.                         }  
  33.                     </tbody>  
  34.                 </table>  
  35.             </div>  
  36.         </div>  
  37.     </div>  
  38. </div>  
  40. @section Scripts  
  41. {  
  43.  <script type="text/javascript">  
  44.      $(document).ready(function () {  
  46.          $('#assets-data-table').DataTable();  
  47.      });  
  48.     </script>     
  50. }  
Now, run the application and you will see a Grid with sorting, searching, and filtering available in it. But, there is one problem -  it is processed on client side. All the data is rendered by View when action is called, which may make page performance slow or increase the page load time if there is a large number of rows coming.
We will be seeing in another post, how we can make it better, using server side paging, sorting, and filtering which surely is a better approach when we have huge data set.