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".
只需确保您已检查以下步骤:
services.AddDistributedMemoryCache()
内存配置为缓存。
services.AddSession()
您已配置会话。
- 这是人们犯错误的地方
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 应该也可以。
我正在登录页面中保存会话变量,
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".
只需确保您已检查以下步骤:
services.AddDistributedMemoryCache()
内存配置为缓存。services.AddSession()
您已配置会话。- 这是人们犯错误的地方
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 应该也可以。