Asp.net-mvc – ASP.NET MVC Session vs Global vs Cache

asp.net-mvccachingsession-state

I have an application that was written in vanilla ASP.NET that I would like to port over to ASP.NET MVC.

I, however, am confused about the right place to persist objects. I need to persist for a couple reasons:

  1. I would like all to have a single database connection, wrapped in a "repository" or "manager" style object.
  2. Each user has a user object that needs to be saved on a per-session basis.

Normally, I would say that #1 would be saved as a static item in the Globals.asax that can be hit using Global.Repository or similar.

And I would normally say that #2 should be a property with a session backing store somewhere in the base class of the pages.

Now the reason I am confused is that I have heard that sessions have changed in MVC, and the Global.asax no longer holds the same class. Also, the concept of pages has been removed, so adding a property to the base class of a controller seems… wrong.

What say yall?

Best Solution

Your database would go in a base class for your controllers. This base class should extend Controller, and all your controllers should extend the base class. Here's a little example:

public class BaseController : Controller
{
    private AuthServices _auth;
    private LogHelper _log;
    private Repository _repository;

    /// <summary>
    /// <see cref="AuthServices"/>
    /// </summary>
    protected AuthServices Authorization
    {
        get { return _auth ?? (_auth = new AuthServices()); }
    }

    /// <summary>
    /// <see cref="LogHelper"/>
    /// </summary>
    protected LogHelper Log
    {
        get { return _log ?? (_log = new LogHelper()); }
    }

    /// <summary>
    /// <see cref="Repository"/>
    /// </summary>
    protected Repository Repository
    {
        get { return _repository ?? (_repository = new Repository()); }
    }
}

Notice the lazy instantiation. That allows me to sneak in before running tests and set my private fields with mocks.

As for the session, your User object can still be saved in the session just as in a traditional ASP.NET application. Almost everything is still around (Response, Cache, Session, etc), but some of them have been wrapped with classes from System.Web.Abstractions so that they can be mocked for testing. They all still behave the same way, though you shouldn't use some of them in their traditional role (e.g., don't Response.Redirect, return an ActionResult such as RedirectToRouteResult that performs your redirection).

As for the reasoning behind your questions....

Don't stress on a single db connection. Depending on your implementation it may even be a bad idea, as requests may step on each other. Just open your connex, use it, and dispose/close it when done.

Also, one of the biggest changes that MVC brings is the rejection of the stateful model that traditional ASP.NET attempted to bring to web development. All that framework and viewstate doesn't exist anymore (pay no attention to the man behind the curtain). The less state you hold onto the less complex and more robust your web application is. Try it, you might like it.