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
Session can be enabled using the Configure method. Inside this method, you will have to call the UseSession method of the app object. Note: It is mandatory to call the UseSession method before the UseMvc method. //Enable Session.
Session state is an ASP.NET Core scenario for storage of user data while the user browses a web app. Session state uses a store maintained by the app to persist data across requests from a client. The session data is backed by a cache and considered ephemeral data.
The Session object is set using the SetString method of the HttpContext. Session property. When the Get Session Button is clicked, the following Handler method is executed. Inside this Handler method, the Session variable name is received as parameter.
In asp.net, It is very simple to detect session time out and redirect the user to login page or home page. All you have to do is, specify the redirection page in session_start event handler in Global. asax file as shown below. If the session has timed out, the user will be redirected to the login page.
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 below
Make sure the Startup.cs
file has session related entries as
shown in Startup.cs
file below
Run the app and click on Home
link on top bar. This will store
the session values shown below (Nam Wam
, 2017
, and current date
)
Click on the About
link on the top bar. You will notice that
session values were passed to About
controller. But I know that
was not your question as this only test the passing of session
values to another action on the same
controller. So, to answer
your question, follow the next 3 steps.
Create another controller AnotherController
- as shown below -
with a new action Test()
and a View Test.cshtml
inside a
Views\Test
folder
In _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 below
Run the app again and first click on the Home
link on the top
bar. Then click on the Test
link on the top bar. You will notice
that the session values were passed from HomController
to the
AnotherController
and were successfully displayed on the Test
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?}");
});
}
....
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With