45

I am setting a session variable in one method and trying to get the session variable value from the another method in a controller but its always getting null:

Here is my code:

public class HomeController : Controller
{
    public IActionResult Index()
    { 
        HttpContext.Session.SetString("Test", "Hello!");
        var message = HttpContext.Session.GetString("Test");// Here value is getting correctly
        return View();
    }

    public IActionResult About()
    {
        var message = HttpContext.Session.GetString("Test"); // This value is always getting null here

        return View();
    }
}

Here is my session configuration in Startup class:

In ConfigureServices() method:

services.Configure<CookiePolicyOptions>(options =>
{
    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
    options.CheckConsentNeeded = context => true;
    options.MinimumSameSitePolicy = SameSiteMode.None;
});

services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddDistributedMemoryCache();
services.AddMvc().AddSessionStateTempDataProvider();
services.AddSession(options =>
{
    options.Cookie.Name = "TanvirArjel.Session";
    options.IdleTimeout = TimeSpan.FromDays(1);
});

In Configure() method:

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

Very strange and peculiar problem! Any help will be highly appreciated!

TanvirArjel
  • 30,049
  • 14
  • 78
  • 114

5 Answers5

85

For ASP.NET Core 2.1 and 2.2

In the ConfigureServices method of the Startup class, Set options.CheckConsentNeeded = context => false; as follows:

services.Configure<CookiePolicyOptions>(options =>
{
  // This lambda determines whether user consent for non-essential cookies is needed for a given request.
  options.CheckConsentNeeded = context => false;
  options.MinimumSameSitePolicy = SameSiteMode.None;
});

Problem solved!

ken2k
  • 48,145
  • 10
  • 116
  • 176
TanvirArjel
  • 30,049
  • 14
  • 78
  • 114
  • Works for me in asp.net Core 2.1 mvc web app! Great Thanks – PatsonLeaner May 15 '19 at 11:59
  • This worked for me. Thank you. Some others suggested adding services.AddMemoryCache() to ConfigureServices and app.UseCookiePolicy() to Configure, but that wasn't necessary. – MikeDev Jun 04 '19 at 13:25
  • 2
    But doesn't this indicate CheckConsentNeeded is false by default? https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.cookiepolicyoptions.checkconsentneeded?view=aspnetcore-2.2 – user8128167 Jun 12 '19 at 15:10
  • As a boolean property default value is false but during the project template generation default value is set to true. – TanvirArjel Jun 12 '19 at 15:48
  • 10
    Not Working for me. Is there anything else which i can do. – Love Pandey Jul 26 '19 at 16:38
  • Check your start up setting please! – TanvirArjel Jul 26 '19 at 16:40
  • not worked for me to after couple redirections the session ends and I need to login again. – Leon Barkan Nov 05 '19 at 12:50
  • that happens only when I use iis as host in my iis express (from vs2017) the session works fine – Leon Barkan Nov 05 '19 at 12:52
  • This answer and `app.UseSession();` helped me get a hold of session, thanks. – vandsh Mar 26 '20 at 19:42
  • I think the IsEssential cookie option needs also to be present: services.AddSession(options => { options.Cookie.IsEssential = true; }); – JMGH Aug 20 '20 at 22:39
  • This is a bad approach. This will make your website/application non-GDPR compliant. Check Max Favilli's answer. This will fix your problem and still prompt the user for consent. – Sal Alturaigi Jan 05 '21 at 11:29
11

You can also just set Cookie.IsEssential = true as explained here: https://andrewlock.net/session-state-gdpr-and-non-essential-cookies/

There is an overload of services.AddSession() that allows you to configure SessionOptions in your Startup file. You can change various settings such as session timeout, and you can also customise the session cookie. To mark the cookie as essential, set IsEssential to true:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        options.CheckConsentNeeded = context => true; // consent required
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddSession(opts => 
    {
        opts.Cookie.IsEssential = true; // make the session cookie Essential
    });
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
Lucca Ferri
  • 1,308
  • 12
  • 23
Max Favilli
  • 6,161
  • 3
  • 42
  • 62
3

I have had the same issue and tried the following separately and I found that either of them does work for me!

 1. options.CheckConsentNeeded = context => false;
 2. opts.Cookie.IsEssential = true; // make the session cookie Essential

However, not quite sure though, I think #1 might potentially lead to the breach of GDPR. Hence I would prefer #2.

Mujib Khan
  • 206
  • 2
  • 5
0

This might be a front end configuration issue.

The session issue you're experiencing might be due to the configuration of your front-end application. If you're using a separate front-end application (e.g. Angular, React, or Vue.js) to interact with your ASP.NET Core API, make sure the HTTP requests sent to the API include the necessary information for handling sessions (and save cookies in the browser).

If your session is persisted between two requests using Postman or Swagger, this is probably it.

i.e. to fix this on an Angular front-end, you must add this in the HttpClient options of your requests: { withCredentials: true }

Matthieu Charbonnier
  • 2,794
  • 25
  • 33
-1

I tried adding the mentioned lines from Microsoft docs on session it didn't work.

As I see from the code of HttpContext.Session Session can be used in the same request. HttpContext.Session

So at last, I created one static class as below which helped as Session throughout the application.

public static class SessionHelper
    {
        private static IDictionary<string, string> Session { get; set; } = new Dictionary<string, string>();

        public static void setString(string key, string value)
        {
            Session[key] = value;
        }

        public static string getString(string key)
        {
            return Session.ContainsKey(key) ? Session[key] : string.Empty;
        }
    }

Usage:

set string in one request

SessionHelper.setString("UserId", "123");

read string in another request

SessionHelper.getString("UserId");

Hope it helps!

Chirag Sheth
  • 99
  • 11