January 2018 : Instructor-led Online Course in ASP.NET Core 2.0. Conducted by Bipin Joshi. Read more...
Registration for January 2018 batch of ASP.NET Core 2.0 instructor-led online course has already started. Conducted by Bipin Joshi. Register today ! Click here for more details.

Use Session in ASP.NET Core 1.0

ASP.NET developers often use Session object to store session wide data. Storing and retrieving values in the Session object is quite straightforward in ASP.NET web forms and ASP.NET MVC. However, ASP.NET Core deal with the session data in a different way. This article introduces you to the foundations of session data management in ASP.NET Core.

To illustrate how data can be stored and retrieved in the Session object under ASP.NET Core, create a new ASP.NET web application. The first step in using Session in ASP.NET Core is to reference the required NuGet package as shown below (Project.json).

"dependencies": {
   ...
  "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
  "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final",
  "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final",
  "Microsoft.AspNet.Tooling.Razor": "1.0.0-rc1-final",
  "Microsoft.Extensions.Configuration.Abstractions": 
                               "1.0.0-rc1-final",
  "Microsoft.Extensions.Configuration.Json": 
                               "1.0.0-rc1-final",
  "Microsoft.AspNet.Session": "1.0.0-rc1-final",
  "Newtonsoft.Json": "8.0.3"
}

As you can see, the above configuration uses Microsoft.AspNet.Session assembly. Also needed is a reference to Newtonsoft.Json component. The Json.Net component is required to serialize and de-serialize objects to and from strings (you will learn more about this later in this article).

Then open the Startup.cs file and modify the ConfigureServices() and Configure() methods as shown below:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddCaching();
    services.AddSession();
}

public void Configure(IApplicationBuilder app)
{
    app.UseIISPlatformHandler();
    app.UseSession();
    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/
                       {action=Index}/{id?}");
    });
}

The ConfigureServices() method adds the in-memory caching service and session service using the AddCaching() and AddSession() methods. The Configure() method then indicates that the application uses the session service using the UseSession() method.

Now add HomeController to the Controllers folder and add the following actions to it:

public IActionResult Index()
{
    HttpContext.Session.SetString("message", 
                        "Hello World!");
    HttpContext.Session.SetInt32("count", 4);
    return View();
}
public IActionResult Index2()
{
            
    ViewBag.Message = HttpContext.Session.
                      GetString("message");
    ViewBag.Count = HttpContext.Session.
                      GetInt32("count");
    return View();
}

The Index() action gets the access to the Session object through the HttpContext object. The SetString() and SetInt32() extension methods are then used to store a string value and an integer value into the session. Both these methods take two parameters - key name and the value. Note that you need to import Microsoft.AspNet.Http namespace to use these extension methods.

The Index2() action uses the GetString() and GetInt32() methods are used to retrieve the previously stored session values. The values thus retrieved are stored in the ViewBag.

Next, add two views - Index.cshtml and Index2.cshtml - and write the following markup in them.

Index.cshtml
============
<h2>@Html.ActionLink("Go to Index2", "Index2")</h2>
Index2.cshtml
=============
<h2>@ViewBag.Message</h2>
<h2>@ViewBag.Count</h2>

If you run the application and click on the "Go To Index2" link you should see the values stored in the session (see below).

So far so good. However, you must that guessed by now that although storing and retrieving strings and integers in the session is good, that's too limiting. At times you need to store complex types - objects - into the session. There is no way to directly store objects into the ASP.NET Core's session. This is because ASP.NET Core is designed to support distributed sessions. So, object references can't be stored in the session. Luckily, you can roll out your own way to store and retrieve entire objects. Let's see how.

Although you can't store an object directly into the session, you can convert an object to its JSON equivalent and then store this JSON string data into the session. While retrieving the object stored in the session you need to convert the JSON string back into an object. You can accomplish this object to JSON conversion using the Json.Net component.

Suppose you have Employee class as shown below:

public class Employee
{
    public int EmployeeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

And you wish to store an Employee object into the session.

To perform the object to JSON and JSON to object conversion let's write a set of extension methods. Have a look at the following code:

public static class SessionExtensionMethods
{
    public static void SetObject(this ISession session, 
                       string key, object value)
    {
        string stringValue = JsonConvert.
                             SerializeObject(value);
        session.SetString(key, stringValue);
    }

    public static T GetObject<T>(this ISession session, 
                                 string key)
    {
        string stringValue = session.GetString(key);
        T value = JsonConvert.DeserializeObject<T>
                              (stringValue);
        return value;
    }
}

The static class SessionExtensionMethods consists of two extension methods namely SetObject() and GetObject().

The SetObject() extension method extends ISession. It accepts a key name and an object that is to be stored in the session. Inside, SerializeObject() method of JsonConvert is used to convert the supplied object into a JSON string. The JSON string thus obtained is then stored in the session using the SetString() method.

The GetObject() generic extension method accepts a key name. Inside, it reads the JSON string for the specified key and parses it to get an object. This is done using the DeserializeObject() method of JsonConvert. The object is then returned to the caller.

Once the SetObject() and GetObject() extension methods are reader, you can use then as follows:

public IActionResult Index()
{
    ....
    Employee emp = new Employee() 
                   { 
                     EmployeeID = 1, 
                     FirstName = "Nancy", 
                     LastName = "Davolio" };
    HttpContext.Session.SetObject("emp", emp);
    return View();
}

public IActionResult Index2()
{
    ...
    ViewBag.Employee = HttpContext.Session.
                       GetObject<Employee>("emp");
    return View();
}

The Index() action now creates and Employee object and stores it in the session using SetObject() extension method. The Index2() action retrieves the Employee object using the GetObject() extension method. The following figure shows a sample run of the application after using SetObject() and GetObject():

In the examples so far you accessed the session inside a controller class. At times you may need to access the session inside some class that is not a controller (say a business logic class). In such cases you can't grab the HttpContext object inside that class. This is so because HttpContext has been exposed as a property of the Controller base class. Luckily, you can use dependency injection to inject IHttpContextAccessor into such a class. The IHttpContextAccessor object then allows you to access the HttpContext.

Let's quickly see how this is done. Look at the following class:

public class MyHelperClass
{
    private IHttpContextAccessor httpContextAccessor;

    public MyHelperClass(IHttpContextAccessor obj)
    {
        this.httpContextAccessor = obj;
    }

    public string Message
    {
        get
        {
            return httpContextAccessor.HttpContext.
                   Session.GetString("message");
        }
    }

    public int Count
    {
        get
        {
            return httpContextAccessor.HttpContext.
                   Session.GetInt32("count").Value;
        }
    }
}

The MyHelperClass class is the class that requires to access the session. The code declares a private variable of type IHttpContextAccessor (Microsoft.AspNet.Http namespace). This variable is assigned a value in the constructor. The constructor receives an IHttpContextAccessor object from the DI framework. The Message and Count read-only properties then return the message and count values from the Session.

Note that you need to register MyHelperClass with the DI framework. You can do so in the ConfigureServices() method in Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
    ....
    services.AddScoped<SessionDemo.Models.MyModel>();
}

To test the working of MyHelperClass, modify the HomeController as shown below:

public class HomeController : Controller
{
    private MyHelperClass helper;

    public HomeController(MyHelperClass obj)
    {
        this.helper = obj;
    }
    ....
}

The above code injects MyHelperClass object into the HomeController. You can then use this object to read the message and count keys.

ViewBag.Message = helper.Message;
ViewBag.Count = helper.Count;

That's it! Keep coding!!


Bipin Joshi is a software consultant, an author and a yoga mentor having 22+ years of experience in software development. He also conducts online courses in ASP.NET MVC / Core and Design Patterns. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 18 April 2016


Tags : ASP.NET ASP.NET Core MVC C#