Asp.Net 核心 Razor 页面,无法从其他 views/razor 模型访问会话变量

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

我正在登录页面中保存会话变量,

Guid sessionId = Guid.NewGuid();

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

现在我像这样访问这个变量:

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

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

return Page();

我在声明会话 ID 的同一个 razor 页面(登录页面)上使用此代码,但是如果我在任何其他 razor 视图页面中使用上述代码,我将无法访问此会话变量。它只能在保存它的同一页面上访问。

我可能做错了什么?

我认为您需要在 .Net Core 中使用 Context.Session.TryGetValue 而不是 HttpContext

您需要在视图中使用 @using Microsoft.AspNetCore.Http; 命名空间

您应该先在 Startup.cs 中配置 HttpContextAccessor 和 Session。

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

//Configure
app.UseSession();

然后你可以在任何地方访问 IHttpContextAccessor 上的 HttpContext。我在索引操作中设置了会话。

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();
    }
}

并在 About.cshtml

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

希望这对您有所帮助。

您需要存储会话数据。大多数应用程序都可以使用内存缓存。您可以在 ConfigureServices 方法中使用 services.AddMemoryCache() 启用它。参见 https://www.learnrazorpages.com/razor-pages/session-state

我不得不更改我之前评论的整个上下文。这里是 "Correct Answer".

只需确保您已检查以下步骤:

  1. services.AddDistributedMemoryCache() 内存配置为缓存。
  2. services.AddSession() 您已配置会话。
  3. 这是人们犯错误的地方 app.UseSession() 必须在 app.UseCookiePolicy() 之后和 app.UseMvc() 之前调用。

**请注意,RedirectToPage()调用根本不会 affect/change 会话变量。 **

这些步骤看起来很简单,但实际上第 3 步就是您要寻找的答案。您的代码看起来非常好。

这是 Rick Anderson 和 Steve Smith 概述的中间件排序 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware/index?view=aspnetcore-2.2#order

有时问题可能是由于您在配置 CookiePolicyOptions 时将 CheckConsentNeeded = context => true 设置为 true 引起的。如果您配置了 <CookiePolicyOptions>,只需将其设置为 false。如果您想将其保留为真,则必须配置 cookie 并设置 Cookie.IsEssential = true; 然后会话将在任何重定向操作中继续存在。

出于安全原因,我不建议使用会话变量。但是,如果您需要在会话之间存储数据,但 ViewBag 不够用,我建议您根据登录用户构建自己的数据并将其存储在数据库中:

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

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

如果您不能使用登录名,请使用唯一的“会话变量”GUID 而不是用户身份名称。两种方式都可以:

Guid id = Guid.NewGuid()

Session 变量的工作方式并不安全,并且(坦率地说)在 Razor 中故意(并且过度)困难且不切实际。查询字符串也不安全。但是根据内部用户名或随机 GUID 将它们存储在数据库中是非常安全的。

不客气。编写 SetGUIDsessionVariable() 和 GetGUIDsessionVariable() 的代码由您自己决定。我是在 SQL 服务器上做的,但 Entity Framework 应该也可以。