Practical .NET
ASP.NET MVC: Improving Productivity with the WebGrid
The WebGrid will certainly make the developers who use it more productive. But is it missing the point of the ASP.NET MVC model?
I appreciate ASP.NET MVC's support for Test Driven Development but I'm less excited about gaining complete control over the HTML that goes down to the browser. My HTML skills are pretty minimal but, really, I feel that generating all that HTML (and potentially JavaScript) makes me less productive than when I'm working in ASP.NET (even after adjusting for losing some of the benefits of TDD). I'd rather drag a GridView onto the page than generate an HTML table. Speaking of which, ASP.NET MVC 3 helps by adding the WebGrid helper and it's a pretty good grid... for MVC.
Displaying Data
Using the WebGrid can require up to three steps. First, you configure the WebGrid. The WebGrid's constructor accepts a lot of parameters but named parameters make this much easier to do and easier for the next developer to understand. This code is pretty much self-explanatory, for instance:
@Code
Dim Grid = New WebGrid(source:=Me.Model,
defaultSort:="FirstName",
rowsPerPage:=3)
End Code
While the source parameter can be set to any collection of objects, here I've bound it to the View's Model property, which, I've assumed, is set in the controller before the View is called.
Then you configure each of the WebGridColumns you want to add to the WebGrid (this part is optional: if you don't configure any columns, the WebGrid displays a column for every property on the objects in the model). WebGridColumns have only four properties: one to bind the column to some property on the objects being displayed (ColumnName), a second to enable sorting on the column by the user (CanSort), a third to hold the text for the column's header (Header), and a fourth to control formatting (format). Once you've configured those columns, you can use the WebGrid's Columns method to load them into an array for use later:
@Code
Dim wbgBD As New WebGridColumn
wbgBD.CanSort = True
wbgBD.ColumnName = "FirstName"
wbgBD.Header = "First Name"
'... configure more columns...
Dim cols As WebGridColumn()
cols = Grid.Columns(wbgFN, wbgLN, wbgBD)
End Code
Once you have the WebGrid configured, you generate your HTML by calling the WebGrid's GetHtml method. In this example, I've just set the style for the table and its header by specifying CSS classes and passed the columns to display:
@Grid.GetHtml(
TableStyle:="gridStyle",
headerStyle:="headStyle",
columns:=cols
To support more than just displaying data you need to let the user select a row. The easiest way to support that is to add another column that isn't tied to a property in the model. Instead, use the column's Format property to call the WebGridRow's GetSelectLink method, passing the text you want to display in the column. This code will generate a column with a column containing a link displaying the text "Edit":
Dim wbgEd As New WebGridColumn
wbgEd.CanSort = True
wbgEd.ColumnName = Nothing
wbgEd.Header = Nothing
wbgEd.Format = Function(row) row.GetSelectLink("Edit")
When the user clicks on the link, the page will postback and the querystring will contain the number of the row that the user selected. You can control the name that the row number is assigned to in the querystring through the selectionFieldName parameter when you instantiate your grid. This example sets the name to "srow":
Dim Grid = New WebGrid(source:=Me.Model,
selectionFieldName:="srow")
If the user clicks on the second row, I'll get a URL something like http://MyHost.com/Home/Index?srow=2.
But Is It A Good Thing?
I'm not concerned with the WebGrid's impact on TDD. In the MVC model, the goal is to have a View that is so brain-dead simple that it can't have errors. Of course, you can still have what I call "blunders" (e.g. the wrong label beside the data or a spelling error in the text on the page), but there's no real opportunity to create logic errors in setting up the WebGrid. Of course, I'm sure I can add some errors in my server-side code when I process the WebGrid row that's passed back when the user selects a row.
But, while I like the WebGrid, I wonder if it doesn't miss the other point of ASP.NET MVC: complete control over your HTML. I think of myself as a practical programmer ("If it works, it's right) rather than a purist, so this kind of issue doesn't worry me much. But one of the reasons that development environments go downhill is that they try to be all things to all geeks. If these new controls are catering to the non-MVC developer, it may be at the risk of generating applications that real MVC developers would regard as a mistake.
About the Author
Peter Vogel is a system architect and principal in PH&V Information Services. PH&V provides full-stack consulting from UX design through object modeling to database design. Peter tweets about his VSM columns with the hashtag #vogelarticles. His blog posts on user experience design can be found at http://blog.learningtree.com/tag/ui/.