Sessions in ASP.NET Core 1.0

4.66 (47 votes)

ASP.NET Core 1.0 is being designed so that your application is only dependent on features that it actually needs. This is achieved in large part by creating a composable framework, where the developer opts in to non-essential features - a number of which are baked in to traditional versions of ASP.NET. One of the features that this applies to is Session State. This article looks at how to obtain and use session state in ASP.NET Core 1.0 applications. It has been updated to reflect Release Candidate (RC) 1 of ASP.NET Core 1.0

If you are new to ASP.NET, session state is a mechanism that enables you to store and retrieve user specific values temporarily. These values can be stored for the duration of the visitor's session on your site. In most cases, they are stored in server memory, although options exist for using persistent and/or distributed storage mechanisms if, for example, you are using multiple web servers for your application (web farm etc). This article is only interested in the in-memory option. The type of data you will use session state for is anything that relates to the current user. It might be their name, or a discount level they are entitled to, or anything that you don't want to repeatedly query a database for.

Session management in ASP.NET Core 1.0 is delivered via a pluggable component, or "middleware" and is available in a Nuget package called Microsoft.AspNet.Core.Session. When you use session management, you also need a persistence mechanism for session variables. In-memory storage is also available as an optional package called Microsoft.Extensions.Caching.Memory. To make them available to your application, add the following entries to the dependencies node of your project.json file:

"Microsoft.AspNetCore.Session": "1.0.0l",
"Microsoft.Extensions.Caching.Memory": "1.0.0"

You should see "Restoring..." appear next to the References node in Solution Explorer and the session package being added.

ASP.NET  Core 1.0  Session

Now that the packages are available to your application, you can opt in to using them. You do this in the ConfigureServices method of the Startup class (Startup.cs file).

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();
    services.AddCaching();
    services.AddSession(options => { 
            options.IdleTimeout = TimeSpan.FromMinutes(30); 
            options.CookieName = ".MyApplication";
        });
}

The highlighted lines show the code you need to add to the ConfigureServices method to register both caching and session with the services used in your application. The method takes an Action<SessionOptions> delegate that enables you to change the default options such as the location for session cookies, or the default timeout period (which is 20 minutes as in previous versions). The sample code above sets the timeout value to 30 minutes. This means that if a user is idle for more then 30 minutes, the session expires and its contents are removed from memory (if that is the backing store you choose to use). It also changes the name of the cookie used to manage sessions, which by default is .AspNet.Session.

At this point, you have included the required packages for session management within your solution and then registered them as services. Now you need to tell the application to use the session management features. You do this in the Configure method of the StartUp.cs file, which is where you register all middleware, but make sure you add session to the pipeline before adding MVC. :

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    app.UseSession();
    //removed for brevity
}

You can start setting and getting session values after you have referenced Microsoft.AspNet.Http in your controller:

using Microsoft.AspNet.Http;

There are three methods that enable you to set session values: SetInt32, SetString and Set, which takes a byte array as an argument. This is very different to the traditional session API, which allows you to set a session value by assigning any type to a session key. The new session framework stores items as byte arrays, and internally, SetInt and SetString converts the ints and strings that you pass to a byte array. The main reason behind this decision appears to be to ensure that session values are serialisable for storage on remote servers. The only way to store other types of values is to implement the serialisation to byte arrays yourself. I look at that shortly, but in the meantime, here's how you would use the SetInt32 and SetString methods from within your controller to create and set some session variables:

public IActionResult Index()
{
    HttpContext.Session.SetString("Name", "Mike");
    HttpContext.Session.SetInt32("Age", 21);
    return View();
}

And here's how you might retrieve those values to be passed to a View:

public IActionResult About()
{
    ViewBag.Name = HttpContext.Session.GetString("Name");
    ViewBag.Age = HttpContext.Session.GetInt32("Age");
    return View();
}

There is also a Get method that returns a byte array. As I mentioned earlier, if you want to set other types as session variables, you need to take care of serialisation yourself. You could do this at the point of setting values, but a more reusable approach can be achieved by creating your own extension methods on ISession. The following example shows how you might implement GetBoolean and SetBoolean methods:

public static class SessionExtensions
{
    public static bool? GetBoolean(this ISession session, string key)
    {
        var data = session.Get(key);
        if (data == null)
        {
            return null;
        }
        return BitConverter.ToBoolean(data, 0);
    } 

    public static void SetBoolean(this ISession session, string key, bool value)
    {
        session.Set(key, BitConverter.GetBytes(value));
    }
}

Now you can use these methods too:

public IActionResult Index()
{
    Context.Session.SetString("Name", "Mike");
    Context.Session.SetInt32("Age", 21);
    Context.Session.SetBoolean("Fibber", true);
    return View();
}
public IActionResult About()
{
    ViewBag.Name = Context.Session.GetString("Name");
    ViewBag.Age = Context.Session.GetInt32("Age");
    ViewBag.Liar = Context.Session.GetBoolean("Fibber");
    return View();
}

There are two other methods of interest. One is the Remove method which allows you to delete individual values from the session collection by key:

Context.Session.Remove("Name");

The other is the Clear method. This removes all keys and values associated with the session. There is no obvious counterpart to the pre-ASP.NET Core 1.0 Abandon method which ends the session.

Session Events

Classic ASP.NET includes a couple of session-related events: Session_Start and Session_End, which you can access via global.asax in order to execute code. In ASP.NET Core 1.0 , you can query the session collection using middleware to establish if a session has already been established to replicate the Session_Start event, but there are no plans to introduce an equivalent to Session_End. Since one of the driving forces behind ASP.NET Core 1.0 is "cloud-readiness", the focus on session management design has been to make it work in a distributed scenario. Session_End only ever fired when sessions used inproc mode (local server memory) and the team have stated that they won't add features that only work locally.

Webucator, a specialist provider of online ASP.NET training have produced a video version of this article:

Summary

The purpose of this article is to introduce the fact that session state is an opt-in component in ASP.NET Core 1.0 and features some differences in method names and usage when compared with traditional ASP.NET. The example here used memory as a backing store for session values, although the limitations of this approach are still the same as in previous versions of ASP.NET. Memory is volatile, and cannot be relied upon. It can be cleared as a result of a number of causes outside of the developer's control. In future articles, I will look at alternative persistence stores.

You might also like...

Date Posted:
Last Updated:
Posted by:
Total Views to date: 67163

19 Comments

- Chris R

Nice writeup.

UseInMemorySession wraps UseSession, you don't need both.

- Mike

@Chris,

Thanks for your comment. I've updated the article to reflect that.

- George Kinsman

You could probably create a generic wrapper of Get<T> and Set<T> using JSON as the serialisation method which would be pretty flexible.

- Mike

@George

There's discussion about a Get<T> and Set<T> option here: https://github.com/aspnet/Session/issues/3

- Joel

Great article! But I still have one problem. I'm trying to use Context.Session.SetInt() and Context.Session.GetInt() in _ViewStart.cshtml - when I type the code, those methods are recognized fine. But when I view the page, I'm getting a 500 error "Session has not been configured for this application or request"...?

- Mike

@Joel,

What you report sounds like a bug. Remember that the framework is still in Beta. Nevertheless, you shouldn't really be setting or getting session variables in a ViewStart file.

- Hisham Abdullah Bin Ateya

Thanks Mike for sharing this article. George it will be nice if we let the web developers implement an interface T <-> byte[] ,but you are welcome to share your suggestions in the thread that I already started in the session repo.

- vamsi

good article

- Magnus

One thing that took me a while to figure out, is that the UseSession() must come before UseMVC() in the startup file.

I was looking at an InvalidException in my Context class, when I had put it the other way around.

- Hisham Abdullah Bin Ateya

FYI the Session.GetInt & Context.Session.SetInt have been renamed to Context.Session.GetInt32 & Context.Session.SetInt32

- Mike

@Hisham,

Thanks - I'll update the article when the next CTP is released.

- Dan

Can I ask how these sort of options are affected by the IIS configuration options when hosted in IIS. Will they be ignored, will the options be disabled??

- Mike

@Dan,

Session in ASP.NET 5 is not dependent on IIS in any way. There's nothing in the source code that refers to IIS settings so they will have no effect on your configuration. I have no idea how or if the IIS team will change any part of their management tools to cater for ASP.NET 5.

- frank

Mike can you write up an article showcasing the difference / upgrade paths of ASP.net Web Pages and New MVC 6? The reason I ask, is now these two are in the same boat, but there is next to ZERO documentation on the new Web Pages, and how they can live with MVC

THANKS

- Mike

@frank,

There is no documentation on the new Web Pages framework at the moment because the framework doesn't exist. I am told that a new Web Pages framework will definitely be introduced in ASP.NET 5, but not until after the RTM. Then it should make the first release after that. When there is something to write about, I will most certainly produce some articles.

- prakash

Nice article..thank you....

- Piotrek

Hi,
it seems it doesn't work now. When I use UseInMemorySession, it throws this error: "IApplicationBuilder does not contain definiotion of UseInMemorySession".

I solved it thanks for http://stackoverflow.com/questions/32250659/using-sessions-in-asp-net-5-mvc-6 , but it still doesn't work because I get another error: "the best overload for UseSession does not have parameter configure".

How can I fix it?

- John A Davis

I am so glad I found your blog or whatever you call it. I can see I'm gonna have hours of good stuff to read. Your Net 5 stuff is quickly making me an expert here where I work. Thank you very much.

Someone at MS really should make multiple checkboxes easier to implement. Everyone needs them and checkboxes have always been a bain.

- Alex Logan

Hi Mike.

It might be useful to know that in order to access the context outside a controller, you can inject IHttpContextAccessor into your class.

Recent Comments

Sivu 19/10/2016 08:21
In response to Entity Framework Core TrackGraph For Disconnected Data
Oh that's very very very nice ! Thanks for the write up Mike, much appreciated for the taking the to...

Mark 12/10/2016 16:42
In response to ASP.NET Web Pages vNext or Razor Pages
Although "Web Pages" was removed from the roadmap, has it just been renamed to "Razor Pages"?...

Satyabrata 12/10/2016 09:20
In response to Entity Framework Core TrackGraph For Disconnected Data
Nice article. Please write more articles featuring ASP.Net web pages. Thank you...

Julian 26/09/2016 14:27
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Fantastic, many thanks Mike! Had got half way down this road before finding your article - saved...

Abolfazl Roshanzamir 14/09/2016 05:36
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Nice article. Thanke you so much ....

cyrus 02/09/2016 15:12
In response to ASP.NET Web Pages vNext or Razor Pages
I've got some news. As Damian stated in this link: https://github.com/aspnet/Mvc/issues/5208 “We...

Simon 01/09/2016 08:00
In response to Loading ASP.NET Core MVC Views From A Database Or Other Location
Thanks Mike, nice post and exactly what I was looking for. Like you said, I think I'll opt to the...

dave 20/08/2016 14:57
In response to ASP.NET Web Pages vNext or Razor Pages
Do SimplemembershipProvider in viewpages is supported?...

Steven 18/08/2016 04:40
In response to Entity Framework Code First and Stored Procedures
Can you provide the directives (using statements) you're using for EF7 example?...

yousaid 17/08/2016 22:08
In response to ASP.NET Web Pages vNext or Razor Pages
Increasingly, learning a Microsoft tool is no longer worth the return on investment. Too many tools...