Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access session asp.net core

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

like image 464
Jeinz Hernandez Avatar asked May 22 '17 15:05

Jeinz Hernandez


People also ask

How can we enable session in asp net core?

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.

Can we use session in .NET core?

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.

How can use session in asp net core razor page?

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.

How check session expired in asp net core?

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.


2 Answers

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:

  1. Create an ASP.NET Core MVC app using default template on VS2017

  2. Modify the default Home controller as shown below

  3. Make sure the Startup.cs file has session related entries as shown in Startup.cs file below

  4. 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)

  5. 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.

  6. Create another controller AnotherController - as shown below - with a new action Test() and a View Test.cshtml inside a Views\Test folder

  7. 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

  8. 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?}");
    });
}
....
like image 160
nam Avatar answered Oct 17 '22 05:10

nam


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.

like image 38
Necker Avatar answered Oct 17 '22 03:10

Necker