C# – Is it good practice to save an entire ViewModel in Session (C# ASP.NET MVC)

asp.netasp.net-mvccmvcsession

I have an C# MVC Application which is basically a large application form. We are using a large ViewModel to store all the information the user enters as they pass through multiple steps in the application.

My problem is that certain steps are loading/saved dynamically through AJAX. I need to store some of the database generated IDs in my view model, which is a problem because those IDs won't persist to the next page unless I add something like hidden fields so that they will be populated in the view model when the server posts to the controller. For various reasons I can't always do this, for instance, the sections of the page that dynamically generated through AJAX, also in some cases I can't have these IDs show on the page for security reasons.

So I started moving these IDs into session values. However I got to thinking, why don't I just save the entire view model in session and then update it each time the user submits their form data and hits the controller. Are there any downsides to storing the entire view model in session? Does this go against MVC architecture? Or should I just leave my IDs in session in the ViewModel and only save the database IDs in session something like the code below:

public static int? CustomerAppID
{
        get
        {
            if (HttpContext.Current.Session["CustomerAppID"] != null)
            {
                return (int)HttpContext.Current.Session["CustomerAppID"];
            }
            else
            {
                return null;
            }
        }
        set
        {
            HttpContext.Current.Session["CustomerAppID"] = value;
        }
}

Best Answer

Putting all of your view model data in the session essentially creates global variables. If you have two different view models setting the same session key one will overwrite the other — and you will pull your hair out trying to track down this defect.

If you are only saving the customer Id to the session then that seems OK to me. Even so, limit the number of session variables you are using, and do not use these session variables all over the place.

Generally you should only use session variables in your controllers. These classes exist closest to the HTTP layer of your application. The controller should retrieve and cast data from the session as needed, but then pass that converted data down into deeper layers of the application as parameters to methods.

As soon as you have multiple layers of your application accessing the session directly, you start running into the same pitfalls as global variables. Too many things can access and modify the same data without knowledge of who else might need it. It also makes writing unit tests more difficult, since using the session directly adds the HTTP layer as a dependency to a class that does not directly deal with HTTP.

I have stored view models in the session before. Recently we implemented a "remember your last search" feature, which remembered the search criteria as well as the data returned in the search. We stuffed the entire view model into the session as a way of caching the data. If no view model was found in the session, we created a new instance of it and showed a blank search form. This was all handled in our controller though. Furthermore the view model was composed of simple values like numbers and strings, and other view models. No references to files, HTTP requests, database connections or any other resource that needs to be properly disposed of remained in the view model.

Storing data in the session is useful in a few cases where you want to cache data for use later, but you are able to recover gracefully in the event that data is missing. Beyond this storing data in the session should be avoided. Pass data from page to page in hidden fields, or query the database for it each time.