Suleman
Suleman

Reputation: 712

Asp.Net Core Razor pages, session variable is not accessible from other views/razor models

I am saving session variable in login page,

Guid sessionId = Guid.NewGuid();

HttpContext.Session.SetString("sessionId",sessionId.ToString());
Response.Cookies.Append("sessionId", sessionId.ToString());

Now I access this variable like this:

string sessionId = Request.Cookies["sessionId"];            

if (!String.IsNullOrEmpty(sessionId) && sessionId.Equals(HttpContext.Session.GetString("sessionId")))
{
    return RedirectToPage("/LoggedIn/Index");
}

return Page();

This code I use on the same razor page (login page) in which session Id is declared, however if I use the above code in any other razor view page, I cannot access this session variable. It is only accessible on the same page it was saved.

What can I possibly be doing wrong ?

Upvotes: 2

Views: 14114

Answers (5)

pianocomposer
pianocomposer

Reputation: 128

I do not recommend using Session Variable for security reasons. However, if you need to store data between sessions but ViewBag is not sufficient, I recommend building your own based on the logged in user and store it in the database:

data.SetGUIDsessionVariable(User.Identity.Name, ThingToStore);

string ThingThatWasStored = data.GetGUIDsessionVariable(User.Identity.Name);

If you cannot use the login name, then use a unique "session variable" GUID instead of the User Identity Name. Either way is fine:

Guid id = Guid.NewGuid()

The way Session variables work is not secure and (quite frankly) is made deliberately (and excessively) difficult and impractical in Razor. Query strings are not secure either. But storing them in the database based on an internal username or random GUID is quite secure.

You're welcome. Writing the code for SetGUIDsessionVariable() ad GetGUIDsessionVariable() is left up to you. I did it in SQL Server but Entity Framework should be possible also.

Upvotes: 0

Mosia Thabo
Mosia Thabo

Reputation: 4267

I had to change the entire context of my previous comment. Here is the "Correct Answer".

Just make sure you have checked below steps:

  1. services.AddDistributedMemoryCache() memory is configured for caching.
  2. services.AddSession() you've configured session.
  3. Here's where people make the mistake app.UseSession() must be called after app.UseCookiePolicy() and before app.UseMvc() .

**Note that a RedirectToPage()call does not affect/change session variables at all. **

These steps look basic but actually step 3 is the answer you're looking for. Your code looks absolutely fine.

Here's the Middleware Ordering as outlined by Rick Anderson and Steve Smith https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/index?view=aspnetcore-2.2#order

Sometimes the problem might be caused by CheckConsentNeeded = context => true being set to true when you configure your CookiePolicyOptions. Just set it to false if you have <CookiePolicyOptions> configured. If you want to leave it as true you must then configure cookie and set Cookie.IsEssential = true; Then the session will survive any redirect action.

Upvotes: 9

Mike Brind
Mike Brind

Reputation: 30065

You need storage for session data. You can use the memory cache for most applications. You enable it with services.AddMemoryCache() in the ConfigureServices method. See https://www.learnrazorpages.com/razor-pages/session-state

Upvotes: 0

ibrahimozgon
ibrahimozgon

Reputation: 1187

You should configure your HttpContextAccessor and Session in Startup.cs first.

//ConfigureServices
services.AddHttpContextAccessor();
services.AddSession(s => s.IdleTimeout = TimeSpan.FromMinutes(30));

and

//Configure
app.UseSession();

Then you can access HttpContext on IHttpContextAccessor anywhere. I've set session in Index action.

public class HomeController : Controller
{
    private readonly IHttpContextAccessor _httpContextAccessor;

    public HomeController(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
    public IActionResult Index()
    {
        _httpContextAccessor.HttpContext.Session.SetString("session1", Guid.NewGuid().ToString());
        return View();
    }
}

And accessed it in About.cshtml

@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor HttpContextAccessor
<h1>Session Value:</h1>
<p>@HttpContextAccessor.HttpContext.Session.GetString("session1")</p>

Hope this helps.

Upvotes: 0

Sean T
Sean T

Reputation: 2494

I believe you need to use Context.Session.TryGetValue as opposed to HttpContext in .Net Core

You will need the @using Microsoft.AspNetCore.Http; namespace in your view

Upvotes: 0

Related Questions