dlras2
dlras2

Reputation: 8486

Do session variables work differently during development?

I'm building a website with ASP.NET MVC3. When a user signs in, I pull their display name from the database and store it to a session variable:

Session["DisplayName"] = user.Display;

Then in _Layout.cshtml I use it to display at the top of each page:

<span class="user">@(Session["DisplayName"] as string)</span>

This works fine when I start debugging the website then log in, but if I then rebuild my server and begin debugging again, my browser remains logged in but the Session variables are cleared. This leads to a bunch of empty spaces where my display name should be.

Is this a side-effect of rebuilding the server, and not something I need to worry about in deployment? Is there a way to invalidate logins every time I rebuild, so that I avoid this issue? Or is there a better way to store this user data, other than a Session variable?

Upvotes: 3

Views: 431

Answers (3)

Adam Tuliper
Adam Tuliper

Reputation: 30152

There are better ways, but to address your specific issue your auth timeout and session timeout are not the same, you need to handle the case specifically when one will timeout before the other. See my post here:

How can I handle forms authentication timeout exceptions in ASP.NET?

Upvotes: 0

Dimitri
Dimitri

Reputation: 7013

Store usernames in cache (Cache[string.Format("DisplayName_{0}", User.Id)] = User.Username), cookies or move session to SQL Server instead of InProc

I would create a static helper method that gets username by user id. If it finds cached value, it will use that, if not, get value from db, store it in cache and return.

public static string GetUsername(int UserID)
{
    string cacheKey=string.Format("DisplayName_{0}", UserID);
    if (HttpContext.Current.Cache[cacheKey]==null)
    {
        // Retrieve user name from DB
        string Username=Repository.GetUserName(UserID);
        HttpContext.Current.Cache[cacheKey]=Username;
    }

    return HttpContext.Current.Cache[cacheKey].ToString();
} 

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038720

Is this a side-effect of rebuilding the server, and not something I need to worry about in deployment?

Oh no, that's something that you absolutely should worry about. As you know ASP.NET session is by default stored in server memory. And when the AppDomain is recycled (which could happen at absolutely any time) by IIS all your session is gone. For example IIS could bring down the AppDomain after a certain inactivity on the application. Or after certain CPU or memory usage thresholds are reached. If you want to be able to reliable store something in the ASP.NET session you could offload the storage off-proc and store this session either in a dedicated session server or SQL. But honestly, I have seen many people moving ASP.NET Session to SQL Server and regretting it. What's the point? You already have this information in SQL Server :-) I once used this and regretted it so much.

Personally I never use ASP.NET Session in my applications. If you need to persist such information as the display name and avoid hitting the database at each request you could store it in the User Data section of the Forms Authentication cookie. So here's the idea: when the user successfully inputs correct credentials, you manually create a FormsAuthenticationTicket and populate its UserData property with whatever information you want to be available about this use on each request and then emit the authentication cookie. Then you write a custom Authorize attribute in which you decrypt the cookie, fetch the User Data and store it as a custom IIdentity making it available on each request.

Upvotes: 4

Related Questions