I've been spending a bit of time over the past month looking into ALL of ASP.NET, not just MVC or SignalR or WebAPI. I've even gone back and spent some time with good old WebForms. When we think back to ASP.NET webforms, many of us cringe and get upset when we think about ViewState
, ClientId
naming, and PostBack
processing. However, I think there are some really good things in WebForms that many of us need to be reminded of. Let's take a look at a quick sample, comparing a "modern" MVC AJAX approach to a web page being built with the tried and true WebForms approach.
Our Data Sample
To start, I'm going to create an MVC4 project in Visual Studio and add the EntityFramework.SqlServerCompact
nuget package. With this in place, I created a Product
object and a simple data context using Entity Framework Code First:
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string Manufacturer { get; set; }
public decimal Price { get; set; }
}
public class ProductContext : DbContext
{
public DbSet<product> Products { get; set; }
}
public class ProductDbInitializer : DropCreateDatabaseAlways<productcontext>
{
protected override void Seed(ProductContext context)
{
var checkers = new Product()
{
ProductId = 1,
Name = "Checkers",
Manufacturer = "Milton Bradley",
Price = 5.99M
};
context.Products.Add(checkers);
var chess = new Product
{
ProductId = 2,
Name = "Chess",
Manufacturer = "Parker Brothers",
Price = 8.99M
};
context.Products.Add(chess);
var backgammon = new Product
{
ProductId = 3,
Name = "Backgammon",
Manufacturer = "Hasbro",
Price = 12.99M
};
context.Products.Add(backgammon);
var connectFour = new Product
{
ProductId = 4,
Name = "Connect Four",
Manufacturer = "Milton Bradley",
Price = 7.49M
};
context.Products.Add(connectFour);
base.Seed(context);
}
}
</productcontext></product>
Note the DbInitializer
class - this will create some seed data for us to display in this sample.
The 'standard' MVC Approach
Typically, an MVC view will output a grid of data with a simple for
-loop over some data. With the razor-formatting engine, this becomes a trivial piece of work in our view:
@foreach (var product in Model)
{
<tr>
<td>@Html.ActionLink(product.Name, "Details", new { id = product.ProductId })</td>
<td>@product.Manufacturer</td>
<td>@product.Price.ToString("$0.00")</td>
</tr>
}
This is a simple approach that dumps the data to screen. For a prototype, it may be enough, but in today's web, we want something more dynamic. We'd prefer an AJAX solution that allows us to search, sort and flip through pages of content.
The output of our simple MVC foreach
loop
If you're like me, you went looking for a jQuery plug in to do some of this work for you. There are a number of great grid controls available like KendoUI or jqGrid. I first used the jqGrid and ran into configuration after configuration that was undocumented that I needed to test and ensure it behaved the way I needed it to. Then I had to chase down a handful of additional methods I needed to add to my MVC controllers to perform the search and sort operations. After that, I had to update those controller methods to handle paging. All in all, I ended up adding more server-side methods in my MVC controller and writing client-side JavaScript wrapper methods for the grid control to simplify my data access needs. I could move my data searching and sorting methods on the server-side into an ApiController
, but my problem remains the same: I'm writing a lot of code to massage the data in the grid to fit my user's needs.
A jqGrid implementation of our grid using ASP.NET MVC.
The WebForms AJAX Way
If we go back to the WebForms technique using the standard gridview
control, we could directly databind to our Products DbSet
in our context. Our construction steps would be as simple as this:
- Drag a
LinqDataSource
onto the webform designer surface - Configure the
LinqDataSource
to connect to our ProductContext
and use the Products dataset
- Drag a
GridView
onto the webform designer surface - Connect the
GridView
to the LinqDataSource
- Configure the
GridView
to enable paging and sorting
Done... I've written no code, and using only the designer tools, I have a functional grid. However, this doesn't have the cool filtering and AJAX features like our jqGrid. We can theme the GridView
easily, but it's still not quite... polished. We would need to add additional controls to the page and additional code to connect some filter controls to the grid.
Standard ASP.NET WebForms GridView control
Enter a Commercial Grid
A commercial grid control will take our capabilities on the WebForm even further, with even less work. Let's consider the Telerik ASP.NET Grid... With Telerik's grid, we need to configure our web project to handle the Telerik controls by adding some entries into web.config. These can be copied directly from another Telerik ASP.NET controls project. Once those settings are in place, adding and configuring our grid is as simple as:
- Drag a
LinqDataSource
onto the webform designer surface - Configure the
LinqDataSource
to connect to our ProductContext
and use the Products dataset
- Drag a
RadGrid
onto designer surface - From the
RadGrid
smart-tag, click the linkbuttons to add the RadScriptManager
and RadAJAXManager
- From the
RadGrid
smart-tag, click the checkboxes to turn on the sorting, filtering, and paging functionality as desired - From the
RadAJAXManager
smart-tag, click the checkboxes to enable the RadGrid
as an AJAX trigger and enable the RadGrid
as an AJAX target
A simple Telerik ASP.NET Grid with just a few of its features enabled
Without any coding, using just the designer tools, I've completed the task again. We now have a grid that will sort, page, and filter on AJAX queries back to the website. Additionally, we can turn on other cool functionality that is built in to the control like "Column Grouping", "Export to Excel" or "Export to PDF". Once again, no coding is needed to enable this functionality. The volume of features in these commercial controls is amazing, and they really are worth it when you look at the time it would take you to build each of these features. There are significant templating and coding options available if you want to turn this Telerik grid into something more unique for your customer.
Summary
The amount of hand coding and mix of client and server side coding to make an MVC solution work just takes too much of my valuable development time. I can put together a great looking webpage very quickly using a WebForms approach. Finally, I can make that WebForm really shine if I use a set of controls from a vendor that are really polished. ASP.NET developers, don't limit your projects to just MVC or WebForms. Try mixing and matching capabilities to make your development tasks easier.