Published: 13 Jun 2011
By: Justin Schwartzenberger
Download Sample Code

Work with Session data without a page reload or redirect using jQuery and JSON data in an ASP.NET MVC 3 application.

Contents [hide]

Use case and goals

Often times in building a web application we have the need to store some type of user configuration for the lifecycle of a user's visit on the site. Typically we turn to the Session to store this data and we accomplish that by posting some type of form data to a server side script and then reloading the page.

With ASP.NET MVC 3 it is easy to write up controller actions that work with JSON data and add some jQuery code in views to interface with those actions via Ajax. We can use that approach to capture and post user settings to some server side code and return the user's settings back without having to reload a page or redirect the user.

We will be creating a prototype application that will have a list page that displays a list of data records consisting of a name and a description. It will allow the user to set the list view to either rows or a grid of blocks. There will also be an option to show or hide the description. When the user sets their desired options we will store them in the Session state. Finally, we want to update the view without reloading the page.

Scaffolding for read/write with the Session

We begin by creating a class for our settings structure that we will use with model binding to store and work with our JSON data from our view. This allows us to use one key/value pair in our Session state instead of storing a key/value for each of our settings. It also provides us with additional control over our data content, thus we can craft some code to protect ourselves from potential cross site scripting vulnerabilities since we will be receiving post data into our action method. Our class will be named ListSettings and will contain two properties named ListView and ShowDescription.

Listing 1: ListSettings.cs

With our settings class defined we can build out our SettingsController class. This class will contain an action method named Save that will take in a ListSetting object, save it in the Session state, and return the object (we will learn why when we get into the jQuery code later in the article). We will also create an action method named Load that will instantiate a default ListSettings object, get the data in the session (if any) and return it as a JSON object.

Listing 2: SettingsController.cs

Controllers and views for the UX

Next we need to set up our user experience layer. We will add a home page and a list page so we can navigate between the two and test our session state. The HomeController will contain the action methods Index and List. Since we want to handle all of our UX updates via Ajax we do not need to add any logic in here to load up the settings for our display.

Listing 3: HomeController.cs

The Index.cshtml view file contains a heading tag to let us know where we are at.

Listing 4: Index.cshtml

The List.cshtml view file will contain the buttons to set the list view type, a button to toggle the description option and an unordered list of our sample data. We will decorate the unordered list with a CSS class named Hidden that will hide the display of the list until we can determine the user settings via some jQuery. The buttons and the unordered lists will get id attributes so we can target them within our jQuery. The data in the list items will also get CSS classes for some styling and to handle the toggle of the description. The html markup portion of the List.cshtml file looks like:

Before we craft the jQuery code let's build out the CSS that we need. We can add the following CSS to the existing Site.css file that is in the default MVC 3 project.

The Button class styles our span tags to make them look interactive. The Hidden class sets the display to none. We use this class for the unordered list as well as the description elements. Using the ItemListing id, we set a fixed width on the unordered list so our grid layout will be a set number of blocks wide (in this case it will be 3). We also normalize the styling on the unordered list by setting the list type to none and the margin/padding to zero. This will remove the disc glyph and left indention so we can have our list looking like rows or columns of blocks. The Name and Description classes add some styling to our text. Finally, the Rows and Grid classes set the style of the li elements to control the way the list items are viewed. The Rows sets the width of each li to the same width as the unordered list. The Grid sets the width on each one smaller, floats them to the left and adds some margin to the right and bottom of each so they don't run into each other. The width of the unordered list will force the grid blocks to wrap, thus achieving the 3 column look.

The jQuery code in the List.cshtml file will handle the user interaction with the settings buttons and updates to the list view. We begin by defining a settings variable that will be global so our functions can access the data in it. Then we will add the jQuery on document load block to wire up our button clicks and add a call to a function called LoadSettings. The final part of script will be our functions to save and load the settings, a callback function to handle the settings loaded event, and a function to set the list view.

The code for setting the list view type handles setting the ListView property of the settings JavaScript object to the selected list view and calls the SaveSettings method. The SaveSettings method posts the settings object to our Save action method in the SettingsController and upon success receives the returned JSON object from that action method and calls the SetListView function. The code to toggle the description visibility sets the ShowDescription property to the opposite of what it currently is (in effect, toggling its state) and then makes the call to SaveSettings.

The SetListView function makes the view changes to the ItemListing by removing the Hidden class and each of the possible list view classes and then adds the selected list view class (we are using the name of the list type as the name of the CSS class). It also checks the ShowDescription property and either removes or adds the Hidden class on the elements with the Description class.

The LoadSettings function makes a post call to the Load action method in the SettingsController and upon success calls the OnSettingsLoaded function. The OnSettingsLoaded function sets the returned JSON object to our settings global variable and then calls the SetListView function. The reason we need to set the global settings object here is so the event handler for the toggle description button has access to the current settings for the ShowDescription property.

That's all that is needed for our view. The end result for our List.cshtml file:

Listing 5: List.cshtml

The last piece we will add is some navigation in our Layout.cshtml file so we have a way to switch back and forth between the home and list pages.

Listing 6: _Layout.cshtml

Now we can run our application, change up our view settings, and navigate back and forth between the home and list pages to see that our settings are remaining in their proper state.

Adapting to changes in requirements

By setting up our UX layer to save and load our settings via JSON we have decoupled the logic of doing the actual state storage from our display. This allows us to make changes to the way we store those settings without having to change our view. For example, we could change our storage logic to use cookies instead by updating our SettingsController class.

Listing 7: SettingsController.cs

With this approach we are able to store and retrieve data on the fly from our application interface and can respond to the user's request for change with an instant update rather than a page reload. Enhancements to the user experience accomplished with relative ease using MVC and jQuery.

<<  Previous Article Continue reading and see our next or previous articles Next Article >>

About Justin Schwartzenberger

I have been entrenched in web application development for quite a while and have traversed the syntactic jungles of PHP, classic ASP, Visual Basic, VB.NET, and ASP.NET Web Forms. However, I have found a guilty pleasure in ASP.NET MVC since its beta launch and have since refactored my web stack focus...

This author has published 3 articles on DotNetSlackers. View other articles or the complete profile here.

Other articles in this category

Code First Approach using Entity Framework 4.1, Inversion of Control, Unity Framework, Repository and Unit of Work Patterns, and MVC3 Razor View
A detailed introduction about the code first approach using Entity Framework 4.1, Inversion of Contr...
Exception Handling and .Net (A practical approach)
Error Handling has always been crucial for an application in a number of ways. It may affect the exe...
jQuery Mobile ListView
In this article, we're going to look at what JQuery Mobile uses to represent lists, and how capable ...
Book Review: SignalR: Real-time Application Development
A book review of SignalR by Simone.
JQuery Mobile Widgets Overview
An overview of widgets in jQuery Mobile.

You might also be interested in the following related blog posts

Updated SilverTwit Code for MSDN Magazine read more
How do ASP.NET Application_ Events Work read more
CodeDigest.Com Article,Codes,FAQs - April,2009 read more
Using NHibernate with multiple databases read more
What is .NET RIA Services? read more
Convert Web.UI Grid into a data entry spreadsheet read more
Sir DevFishs Crusade of Enlightenment read more
Identity Maps read more
Session Slides and Samples from Microsoft ASP.NET Connections read more
Running the Same Query Against Multiple Databases read more


Subject Author Date
placeholder Really excellent Rick Anderson 7/6/2011 7:34 PM
RE: Really excellent Justin Schwartzenberger 7/6/2011 8:03 PM
placeholder MVC content page Rick Anderson 7/7/2011 11:31 PM
RE: MVC content page Justin Schwartzenberger 7/8/2011 2:31 PM
placeholder RE: MVC content page Justin Schwartzenberger 7/8/2011 12:13 PM

Please login to rate or to leave a comment.