Cannot access session asp.net core
Solution 1
For VS2017
, follow this MSDN official article regarding Session and Application state in ASP.NET Core. You can test your scenario in the following example I've created. Note: Although the code below looks lengthy, you will, in fact, only made some minor changes to the default app that gets created from default ASP.NET Core template. Just follow the steps below:
Create an ASP.NET Core MVC app using default template on
VS2017
Modify the default
Home controller
as shown belowMake sure the
Startup.cs
file has session related entries as shown inStartup.cs
file belowRun the app and click on
Home
link on top bar. This will store the session values shown below (Nam Wam
,2017
, andcurrent date
)Click on the
About
link on the top bar. You will notice that session values were passed toAbout
controller. But I know that was not your question as this only test the passing of session values to another action on thesame
controller. So, to answer your question, follow the next 3 steps.Create another controller
AnotherController
- as shown below - with a new actionTest()
and a ViewTest.cshtml
inside aViews\Test
folderIn
_Layout.cshtml
add another link<li><a asp-area="" asp-controller="Another" asp-action="Test">Test View</a></li>
right after<li>...Contact...</li>
link as shown belowRun the app again and first click on the
Home
link on the top bar. Then click on theTest
link on the top bar. You will notice that the session values were passed fromHomController
to theAnotherController
and were successfully displayed on theTest
View.
HomeController:
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
namespace MyProject.Controllers
{
public class HomeController : Controller
{
const string SessionKeyName = "_Name";
const string SessionKeyFY = "_FY";
const string SessionKeyDate = "_Date";
public IActionResult Index()
{
HttpContext.Session.SetString(SessionKeyName, "Nam Wam");
HttpContext.Session.SetInt32(SessionKeyFY , 2017);
// Requires you add the Set extension method mentioned in the SessionExtensions static class.
HttpContext.Session.Set<DateTime>(SessionKeyDate, DateTime.Now);
return View();
}
public IActionResult About()
{
ViewBag.Name = HttpContext.Session.GetString(SessionKeyName);
ViewBag.FY = HttpContext.Session.GetInt32(SessionKeyFY);
ViewBag.Date = HttpContext.Session.Get<DateTime>(SessionKeyDate);
ViewData["Message"] = "Session State In Asp.Net Core 1.1";
return View();
}
public IActionResult Contact()
{
ViewData["Message"] = "Contact Details";
return View();
}
public IActionResult Error()
{
return View();
}
}
public static class SessionExtensions
{
public static void Set<T>(this ISession session, string key, T value)
{
session.SetString(key, JsonConvert.SerializeObject(value));
}
public static T Get<T>(this ISession session, string key)
{
var value = session.GetString(key);
return value == null ? default(T) : JsonConvert.DeserializeObject<T>(value);
}
}
}
About.cshtml [Displaying session variable values from the same
controller]
@{
ViewData["Title"] = "ASP.Net Core !!";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<table class="table table-responsive">
<tr>
<th>Name</th>
<th>Fiscal Year</th>
</tr>
<tr>
<td>@ViewBag.Name</td>
<td>@ViewBag.FY</td>
</tr>
</table>
<label>Date : @(ViewBag.Date.ToString("dd/MM/yyyy") != "01/01/0001" ? ViewBag.Date.ToString("dd/MM/yyyy") : "")</label>
AnotherController [A different controller than HomeController]:
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
public class AnotherController : Controller
{
const string SessionKeyName = "_Name";
const string SessionKeyFY = "_FY";
const string SessionKeyDate = "_Date";
// GET: /<controller>/
public IActionResult Test()
{
ViewBag.Name = HttpContext.Session.GetString(SessionKeyName);
ViewBag.FY = HttpContext.Session.GetInt32(SessionKeyFY);
ViewBag.Date = HttpContext.Session.Get<DateTime>(SessionKeyDate);
ViewData["Message"] = "Session State passed to different controller";
return View();
}
}
Test.cshtml: [Displaying session variable values passed from Home controller to Another
controller]
@{
ViewData["Title"] = "View sent from AnotherController";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>
<table class="table table-responsive">
<tr>
<th>Test-Name</th>
<th>Test-FY</th>
</tr>
<tr>
<td>@ViewBag.Name</td>
<td>@ViewBag.FY</td>
</tr>
</table>
<label>Date : @(ViewBag.Date.ToString("dd/MM/yyyy") != "01/01/0001" ? ViewBag.Date.ToString("dd/MM/yyyy") : "")</label>
_Layout.cshtml:
....
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
<li><a asp-area="" asp-controller="Another" asp-action="Test">Test View</a></li>
</ul>
</div>
....
Startup.cs: [Make sure you have some session related entries included. Most likely when you created an ASP.NET Core MVC app in VS2017, these entries will already be there. But just make sure.]
....
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
//In-Memory
services.AddDistributedMemoryCache();
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromMinutes(1);//Session Timeout.
});
// Add framework services.
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseSession();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
....
Solution 2
To use Session in your MVC App, you have to:
Install Microsoft.AspNetCore.Session
NuGet package.
In Startup.cs
ConfigureServices
add the AddSession()
:
services.AddMvc();
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromHours(1);
});
In Startup.cs
configure add the UseSession()
:
app.UseSession();
app.UseMvc();
And now you can use it in the controller:
Set the Session
string token="xx";
HttpContext.Session.SetString("UserToken", token);
Get the stored value
var token = HttpContext.Session.GetString("UserToken");
Additionally, ASP.NET Core 2.1+ introduced some additional extension points like a cookie consent dialog. So we require consent to store cookies from the user.
If you click "Accept" on the privacy banner, then ASP.NET Core is able to write the session cookie.
Jeinz Hernandez
Updated on June 17, 2022Comments
-
Jeinz Hernandez almost 2 years
Hi please help me im trying to test sessions in asp.net core but when i set the session and get it from other controller it appears to be null
heres my startup
public class Startup { public IConfigurationRoot Configuration { get; } public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddEnvironmentVariables(); Configuration = builder.Build(); } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // Add framework services. services.AddMvc().AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); // Adds a default in-memory implementation of IDistributedCache. services.AddDistributedMemoryCache(); services.AddSession(options => { // Set a short timeout for easy testing. options.IdleTimeout = TimeSpan.FromSeconds(600); options.CookieHttpOnly = true; }); services.AddSingleton<IConfiguration>(Configuration); services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>(); services.AddTransient<IApiHelper, ApiHelper>(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.UseSession(); app.UseDeveloperExceptionPage(); if (env.IsDevelopment()) { app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { HotModuleReplacement = true, ReactHotModuleReplacement = true }); } //var connectionString = Configuration.GetSection("ConnectionStrings").GetSection("ClientConnection").Value; app.UseStaticFiles(); loggerFactory.AddConsole(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); routes.MapSpaFallbackRoute( name: "spa-fallback", defaults: new { controller = "Home", action = "Index" }); }); } public static void Main(string[] args) { var host = new WebHostBuilder() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseKestrel() .UseStartup<Startup>() .Build(); host.Run(); } }
and here is how i set the session
public class HomeController : Controller { public IActionResult Index() { HttpContext.Session.SetString("Test", "Ben Rules!"); return View(); } public IActionResult Error() { return View(); } }
and here my sample code of getting the session again but it appears to be null
[HttpGet("[action]")] public IEnumerable<JobDescription> GetJobDefinitions() { //this is always null var xd = HttpContext.Session.GetString("Test"); var x = _apiHelper.SendRequest<Boolean>($"api/JobRequest/GetJobRequest",null); var returnValue = new List<JobDescription>(); returnValue = jobDescriptionManager.GetJobDescriptions(); return returnValue; }
Thanks for the help
-
Ilya Chumakov almost 7 yearsMake sure you provided a session cookie to your GET
GetJobDefinitions
request. The cookie should sent to the server with each request. The server uses the session ID from the cookie to fetch the session data. -
Jeinz Hernandez almost 7 yearsHi illya thanks for answering, can you give me raw example thanks
-
Ilya Chumakov almost 7 yearsMake a GET request in browser and look for a cookie named
.AspNet.Session
in devtools. Browser adds it to next requests automatically within a browser session. docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state -
nam almost 7 years@JeinzHernandez Please see my example below that shows how you can pass session values from one controller to another controller in ASP.NET Core. Although example looks long, in reality you will only be making minor changes to the default ASP.NET Core MVC app that is created when we use default ASP.NET Core MVC template in visual studio. Just follow the steps described below.
-