The Ultimate Cookbook for the ASP.NET MVC WebGrid

Most developers new to ASP.NET MVC think they need to use a table tag for their grid capabilities. Today, we cover a number of ASP.NET MVC WebGrid questions to create an ultimate WebGrid resource.

Written by Jonathan "JD" Danylko • Last Updated: • MVC •
WebGrid Cookbook

If you've been reading the site recently, you may have noticed I've provided a lot of WebGrid features in past posts for advanced users. Yet, I haven't discussed the basics of the WebGrid.

This post will be a post that will constantly be updated. It will contain the proverbial "cookbook" for developers looking for answers to WebGrid solutions. 

What is the namespace for an ASP.NET MVC WebGrid?

The WebGrid is located in the System.Web.Helpers namespace.

How do you create a WebGrid?

The simplest way to create a WebGrid is by defining it on your View and calling it from the View.

For example,

@using WebGridExample.Helpers.Html
@using WebGridExample.Models
@model IEnumerable<User>
@{
    var grid = new WebGrid(Model);
}
.
.
@MvcHtmlString.Create(
    grid.GetHtml().ToHtmlString()
)

The WebGrid has a huge number of parameters to pass into the constructor.

Name Type Notes
source IEnumerable<dynamic> The data to render.
columnNames IEnumerable<string> Filters the columns that are rendered.
defaultSort string Specifies the default column to sort by.
rowsPerPage int Controls how many rows are rendered per page (default is 10).
canPage bool Enables or disables paging of data.
canSort bool Enables or disables sorting of data.
ajaxUpdateContainerId string The ID of the grid’s containing element, which enables AJAX support.
ajaxUpdateCallback string The client-side function to call when the AJAX update is complete.
fieldNamePrefix string Prefix for query string fields to support multiple grids.
pageFieldName string Query string field name for page number.
selectionFieldName string Query string field name for selected row number.
sortFieldName string Query string field name for sort column.
sortDirectionFieldName string Query string field name for sort direction.

For the method GetHtml(), there are a ton of parameters for that as well.

Name Type Notes
tableStyle string Table class for styling.
headerStyle string Header row class for styling.
footerStyle string Footer row class for styling.
rowStyle string Row class for styling (odd rows only).
alternatingRowStyle string Row class for styling (even rows only).
selectedRowStyle string Selected row class for styling.
caption string The string displayed as the table caption.
displayHeader bool Indicates whether the header row should be displayed.
fillEmptyRows bool Indicates whether the table can add empty rows to ensure the rowsPerPage row count.
emptyRowCellValue string Value used to populate empty rows; only used when fillEmptyRows is set.
columns IEnumerable<WebGridColumn> Column model for customizing column rendering.
exclusions IEnumerable<string> Columns to exclude when auto-populating columns.
mode WebGridPagerModes Modes for pager rendering (default is NextPrevious and Numeric).
firstText string Text for a link to the first page.
previousText string Text for a link to the previous page.
nextText string Text for a link to the next page.
lastText string Text for a link to the last page.
numericLinksCount int Number of numeric links to display (default is 5).
htmlAttributes object Contains the HTML attributes to set for the element.

I will be covering a number of these parameters, but not all of them. If you want to examine them further, please refer to the MSDN WebGrid docs.

How do you add attributes to a WebGrid?

The best way to add your styles to the WebGrid is to use the htmlAttributes parameter.

@MvcHtmlString.Create(
    grid.GetHtml(
        htmlAttributes: new {
            id = "grid",
            @class = "table table-bordered table-striped table-condensed"
        }
    ).ToHtmlString()
)

However, for the class attribute, you can remove the @class line and move the classes into the tableStyle property.

@MvcHtmlString.Create(
    grid.GetHtml(
        tableStyle: "table table-bordered table-striped table-condensed",
        htmlAttributes: new {
            id = "grid"
        }
    ).ToHtmlString()
)

How do you build WebGrid columns?

The parameters passed into a WebGrid can get lengthy. Pass in the columns using the columns parameter and use the WebGrid's Columns method to define your list of WebGridColumn. 

@MvcHtmlString.Create(
    grid.GetHtml(
        tableStyle: "table table-bordered table-striped table-condensed",
        htmlAttributes: new {
            id = "grid"
        },
        columns: grid.Columns(
            grid.Column("UserName" , "User Name"),
            grid.Column("FirstName""First Name"),
            grid.Column("LastName" ,"Last Name"),
            grid.Column("LastLogin""LastLogin")
        )
    ).ToHtmlString()
)

The first parameter in the Column constructor is the column name and the second parameter is the heading.

Ok, how do you build custom columns?

As I've mentioned before, you don't want to add a ton of code into your views, but you need to render custom data somehow.

By using HtmlHelpers.

In one example of the WebGrid series, I added an Options column for record specific functions and used an HtmlHelper by passing in the User object.

@MvcHtmlString.Create(
    grid.GetHtml(
        tableStyle: "table table-bordered table-striped table-condensed",
        htmlAttributes: new {
            id = "grid"
        },
        columns: grid.Columns(
            grid.Column("UserName" , "User Name", canSort: false),
            grid.Column("FirstName""First Name"),
            grid.Column("LastName" ,"Last Name"),
            grid.Column("Full Name", format: @<text>item.FirstName+" "+item.LastName</text>),
            grid.Column("LastLogin", format: item => item.LastLogin.ToString("d")),
            grid.Column("Options", format: item => 
                Html.DisplayRecordOptions(item.Value as User), canSort: false)
        )
    ).ToHtmlString()
)

When using custom columns, you want to use the format parameter to make your custom column data. Depending on your ViewModel, you could very easily create an HtmlHelper to display anything you wanted in a column (i.e. image, buttons, PDF, etc).

Of course, you don't want the column sorted either, so you can turn sorting off using the canSort property.

Notice the @<text></text> tags? Anything inside of text will be taken literally. So in the FullName column, you'll see:

item.FirstName+" "+item.LastName

As you can see, I included a number of examples of how to format your columns.

If you want an example of the DisplayRecordOptions HtmlHelper, I'll refer you to the ASP.NET MVC: Enhancing the WebGrid - Inline Editing using SignalR post.

If you need a refresher on how to create an HtmlHelper, refer to the ASP.NET MVC HtmlHelpers: Clean up Your Views With HtmlHelpers post.

How can I apply paging to WebGrid?

Paging is defined through the WebGrid constructor.

@{
    var grid = new WebGrid(Model, canPage: true, rowsPerPage: 20);
}

It provides the basic paging mechanism, but I would refrain from using it because it provides paging at the client level as opposed to the server side/database level of paging.

You want the minimal amount of data returned to display a complete View.

If you want to modify the text on the paging, add the First, Previous, Next, and Last properties with the text for each appropriate function.

@MvcHtmlString.Create(
    grid.GetHtml(
        tableStyle: "table table-bordered table-striped table-condensed",
        mode: WebGridPagerModes.All,
        firstText: "First",
        previousText: "Prev",
        nextText: "Next",
        lastText: "Last",
        htmlAttributes: new {
            id = "grid"
        },
        columns: grid.Columns(
            grid.Column("UserName" , "User Name", canSort: false),
            grid.Column("FirstName""First Name"),
            grid.Column("LastName" ,"Last Name"),
            grid.Column("LastLogin", format: item => item.LastLogin.ToString("d")),
            grid.Column("Options", format: item => 
                Html.DisplayRecordOptions(item.Value as User), canSort: false)
        )
    ).ToHtmlString()
)

How do I sort a WebGrid?

By default, a WebGrid defines every column as sortable.

To turn off sorting at the column level, pass in canSort: false (in bold).

@MvcHtmlString.Create(
    grid.GetHtml(
        tableStyle: "table table-bordered table-striped table-condensed",
        htmlAttributes: new {
            id = "grid"
        },
        columns: grid.Columns(
            grid.Column("UserName" , "User Name"canSort: false),
            grid.Column("FirstName""First Name"),
            grid.Column("LastName" ,"Last Name"),
            grid.Column("LastLogin""Last Login"),
            grid.Column("Options", format: item => 
                Html.DisplayRecordOptions(item.Value as User), canSort: false)
        )
    ).ToHtmlString()
)

How can I nest another WebGrid inside another WebGrid?

Remember when I said you can build anything into a WebGrid Column?

If each user belonged to a group, you could add a column displaying their groups in a table.

Here is the nested WebGrid:

@MvcHtmlString.Create(
    grid.GetHtml(
        tableStyle: "table table-bordered table-striped table-condensed",
        htmlAttributes: new {
            id = "grid"
        },
        columns: grid.Columns(
            grid.Column("UserName" , "User Name", canSort: false),
            grid.Column("FirstName""First Name"),
            grid.Column("LastName" ,"Last Name"),
            grid.Column("LastLogin""Last Login"),
            grid.Column("SubGrid", format: (item) =>
            {
                var subGrid = new WebGrid((item.Value as User).Groups);
                return subGrid.GetHtml(
                    tableStyle: "table table-bordered table-condensed",
                    htmlAttributes: new { id="subGrid"},
                    columns: subGrid.Columns(
                        subGrid.Column("Groups", 
                            format: (groupString) => groupString, 
                            canSort: false)
                    )
                );
            }, canSort: false)
        )
    ).ToHtmlString()
)

How can I use AJAX/SignalR with a WebGrid?

If you want a modern web application, learning Ajax and SignalR should be one of your top priorities. SignalR is one of my favorite libraries for performing real-time transactions over the web.

Instead of going over a huge post of how to integrate Ajax or SignalR into your WebGrid, I will refer you to some techniques I covered in my WebGrid Series:

Conclusion

This post will be a living, breathing, document as I continue to use the WebGrid throughout my travels. I will always be expanding this post because of ASP.NET MVC 6 arriving soon.

If anyone is looking for a specific WebGrid topic or technique, please let me know or post a comment below.

ASP.NET 8 Best Practices on Amazon

ASP.NET 8 Best Practices by Jonathan Danylko


Reviewed as a "comprehensive guide" and a "roadmap to excellence" with over 120 Best Practices for ASP.NET Core 8, Jonathan's first book by Packt Publishing explores proven techniques for every phase of the SDLC.

Learn industry-standard concepts to improve your coding, debugging, and deployment of ASP.NET Core websites.

Order now on Amazon.com button

Picture of Jonathan "JD" Danylko

Jonathan "JD" Danylko is an author, web architect, and entrepreneur who's been programming for over 30 years. He's developed websites for small, medium, and Fortune 500 companies since 1996.

He currently works at Insight Enterprises as an Architect.

When asked what he likes to do in his spare time, he replies, "I like to write and I like to code. I also like to write about code."

comments powered by Disqus