Imagine you have created an MVC project and you are all set to create a session object because you want to save your current user email.
But after few minutes you will realize that Session object is not working as it was before.
Oh! Why is it so?
It is because .Net team has created a Nuget package for Session which is nothing but a very fresh ASP.NET 5 session state middle ware.
Ok, so How to get it?
To install Microsoft.AspNet.Session, run the following command in the Package Manager Console
Great, so now we can use Session in vNext right?
Well not yet.
We need to update Startup.cs file as below:
public void ConfigureServices(IServiceCollection services)
{
// Adds a default in-memory implementation of IDistributedCache
services.AddCaching();
services.AddSession();
//// This Method may contain other code as well
}
and in Configure method write below code:
public void Configure(IApplicationBuilder app) { app.UseSession(); //// This Method may contain other code as well }
How to get and set session?
Ok, let us take some examples.
1. Suppose you want to use Session in your controller class:
For that you simply have to write Context.Session to access Session.
Set Session syntax:
public IActionResult Index() { ////Context.Session.SetString("First", "I am first!"); ////Before Beta 8 HttpContext.Session.SetString("First", "I am first!"); ////From Beta 8 onwards return View(); }
Get Session syntax:
public IActionResult Index() { ////var myValue = Context.Session.GetString("First"); ////Before Beta 8 var myValue = HttpContext.Session.GetString("First"); ////From Beta 8 onwards return View(); }
2. Suppose you want to use Session in a normal class:
If you’re not in a controller, you can still access the HttpContext by injecting IHttpContextAccessor as shown below:
private readonly IHttpContextAccessor _httpContextAccessor; public SessionUtility(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; }
Set Session syntax:
public void SetSession(string key, string value) { HttpContextAccessor.HttpContext.Session.SetString(key, value); }
Get Session syntax:
public string GetSession(string key) { return HttpContextAccessor.HttpContext.Session.GetString(key); }
So, whole SessionUtility would be as below:
public class SessionUtility { private readonly IHttpContextAccessor HttpContextAccessor; public SessionUtility (IHttpContextAccessor httpContextAccessor) { HttpContextAccessor = httpContextAccessor; } public void SetSession(string key, string value) { HttpContextAccessor.HttpContext.Session.SetString(key, value); } public string GetSession(string key) { return HttpContextAccessor.HttpContext.Session.GetString(key); } }
and it would be registered as below:
services.AddTransient<SessionUtility>();
Here SessionUtility should be registered only as Transient or Scoped and not Singleton as HttpContext is per-request based.
Please note that i have used it with key value pair of string but you can create same Session utility for complex scenario.
Now, Suppose you want to check how many times a Visitor have visited your site.
For that you need to add below code in your startup.cs:
public void Configure(IApplicationBuilder app) { app.UseSession(); app.Map("/session", subApp => { subApp.Run(async context => { int visits = 0; visits = context.Session.GetInt32("visits") ?? 0; context.Session.SetInt32("visits", ++visits); await context.Response.WriteAsync("Counting: You have visited our page this many times: " + visits); }); }); }
Remember!
If you have follow above steps and you still can not get the success then you might need a look in your project.json file if it contains below piece of code:
"frameworks": { "dnx451": { }, "dnxcore50": { } // <-- Remove this if it is in your project.json file. },
Reason?
Because Asp.Net 5 Sessions aren’t supported by the DNX Core Runtime.
Nuget package site: https://www.nuget.org/packages/Microsoft.AspNet.Session/
Session is still in it’s beta versions so there might some changes would come that will be updated in this post.
Stay tuned for more updates!
Getting Static constructor must be parameterless error. Please help!!
LikeLike
Hello
Thanks for pointing it out.
It was a typo and I have updated the post.
So please have a look again.
Best regards,
Neel
LikeLike
As soon as I add app.UseSession(); I get this error on running:
System.InvalidOperationException: Unable to resolve service for type ‘Microsoft.Framework.Caching.Distributed.IDistributedCache’ while attempting to activate ‘Microsoft.AspNet.Session.DistributedSessionStore’.
at Microsoft.Framework.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Framework.DependencyInjection.ServiceLookup.Service.CreateCallSite(ServiceProvider provider, ISet`1 callSiteChain)
at Microsoft.Framework.DependencyInjection.ServiceProvider.GetResolveCallSite(IService service, ISet`1 callSiteChain)
at Microsoft.Framework.DependencyInjection.ServiceProvider.GetServiceCallSite(Type serviceType, ISet`1 callSiteChain)
at Microsoft.Framework.DependencyInjection.ServiceProvider.b__7_0(Type key)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.Framework.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Framework.Internal.ActivatorUtilities.ConstructorMatcher.CreateInstance(IServiceProvider provider)
at Microsoft.Framework.Internal.ActivatorUtilities.CreateInstance(IServiceProvider provider, Type instanceType, Object[] parameters)
at Microsoft.AspNet.Builder.UseMiddlewareExtensions.c__DisplayClass2_0.b__0(RequestDelegate next)
at Microsoft.AspNet.Builder.Internal.ApplicationBuilder.Build()
at Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()
at Microsoft.AspNet.Hosting.Internal.HostingEngine.Start()
at Microsoft.AspNet.Loader.IIS.RuntimeHttpApplication.ApplicationStart(IHttpApplication application)
at Microsoft.AspNet.Loader.IIS.HttpApplicationBase.InvokeApplicationStart(IHttpApplication application)
LikeLike
Hi Dale,
Have you enabled caching ? you need to add
services.AddCaching();
before
services.AddSession();
because it uses Redis cache!
LikeLike
Neel,
Yes that did it. Thanks!!
Dale
LikeLike
Glat to help Dale!
LikeLike
I have a error when instance class Error CS7036 There is no argument given that corresponds to the required formal parameter ‘httpContextAccessor’ of ‘SessionUtility.SessionUtility(IHttpContextAccessor)’ EjemplosMVC.DNX 4.5.1
LikeLike
Hi Juan, You need to register service. Please see updated post.
LikeLike
Hi, I registred services.AddTransient() in Startup.cs ConfigureServices section. but when i instance from controller
var Sess = new SessionUtility(); show error :There is no argument given that corresponds to the required formal parameter ‘httpContextAccessor’ of ‘SessionUtility.SessionUtility(IHttpContextAccessor)’
public class SessionUtility
{
private readonly IHttpContextAccessor HttpContextAccessor;
public SessionUtility(IHttpContextAccessor httpContextAccessor)
{
HttpContextAccessor = httpContextAccessor;
}
public void SetSession(string key, string value)
{
HttpContextAccessor.HttpContext.Session.SetString(key, value);
}
public string GetSession(string key)
{
return HttpContextAccessor.HttpContext.Session.GetString(key);
}
}
LikeLike
Just a heads up as I was scratching my head why I could not get sessions to work in beta 8. Context property has been renamed HttpContext – See my post https://christopherhackett.co.uk/blog/2015/10/17/ASP.NET-5-MVC-6-renames-in-beta-8/
LikeLike
Hi Christopher, As it has been renamed for only MVC, I have updated accordingly.
Thanks 🙂
LikeLike
So… Sessions require Caching? Is it possible to use in-memory caching for general use at the same time as SQL server backed sessions?
LikeLike
Hi Simon,
I asked .Net team regarding this and they answered as below:
Yes, they shouldn’t interfere with each other. In memory caching is registered as an IMemoryCache, where SQL is registered as an IDistributedCache. Session uses IDistributedCache.
Neel
LikeLike
Thanks, Neel!
I wonder if you know of any samples that show how to properly configure the services object with “In Memory Cache” and simultaneous “Sql Server Sessions”.? I can’t seem to work it out at all.
LikeLike
Hi Simon, I just saw that you have already got answer in Github. Anyways for those who have same doubt can make it work as below:
AddCaching(); // Add IMemoryCache and IDistributedCache
AddSqlServerCache(); // overwrite IDistributedCache registration from AddCaching with SQL backing
AddSession(); // which will now resolve to using SQL backed IDistributedCache
LikeLike
That actually ended up being incorrect. You have to “AddSqlServerCache” *first*. So, it’s
AddSqlServerCache();
AddCaching();
AddSession();
It looks like the behavior is that AddCaching does not overwrite the IDistributedCache added by AddSqlServerCache, but rather makes use of it. If no IDistributedCache has been added by the time you call AddCaching, it adds its own implementation.
I find this behavior confusing since it’s not intuitive (a later call, in my mind, should override an earlier call). ADditionally, since there is no way to know which services each call adds to the pipeline by looking at the method name or the intellisense comments, it becomes a game of searching the source code.
Hopefully the final documentation will at least include this information.
LikeLike
How can i use session in view ?
Rohit
LikeLike
Hi Rohit, You can access the HttpContext in a view using the Context property as below:
@{ var x = Context.Session.GetString(“newTest”); }
LikeLike
Hi,
I have seen this kind of examples using “SessionUtility”, but anyone shows how to use this class. I’m trying to use it, but I need to pass some constructor value.
How can I use this class?
LikeLike