在 ASP.Net 个核心 Razor 页面中使用会话包装器
Using a session wrapper in ASP.Net Core Razor Pages
为了改进我们应用程序中的会话处理,我们想创建一个包装器 class,它通过属性管理会话访问(以防止在使用字符串时出现常见问题)。
像这样:
public class Wrapper
{
public string Username
{
get { return HttpContext.Current.Session.GetString("username"); }
set { HttpContext.Current.Session.SetString("username", value); }
}
}
在 classic ASP.Net 中有很多关于如何实现这一点的示例,但我们无法将它们移植到 ASP.Net Core。关于 ASP.Net Core 中的会话包装器(我能找到)的唯一 other question 是使用 Singleton,我们发现它不适合我们的情况。
我们的问题归结为两个主要问题:
- 如何正确包装和访问另一个 class 中的当前会话(避免反模式和安全问题)
- 如何在我们的应用程序中共享 class
我们决定使用 ASP.Net Core 的依赖注入功能,因为它看起来非常适合这项工作。要访问服务内的会话 IHttpContextAccessor is necessary. As stated in David Fowler's ASP.NET Core Diagnostic Scenarios it is recommended to not store the IHttpContextAccessor.HttpContext
in a field, however using a , since it gets created for each request.
我们的设置
这里我们使用HttpContextAccessor
来引用当前会话。通过使用属性限制对会话的访问(字符串可以进一步替换为常量)。
public class SessionService
{
private readonly ISession _session;
public SessionService(IHttpContextAccessor accessor)
{
_session = accessor.HttpContext.Session;
}
public string Username
{
get { return _session.GetString("username"); }
set { _session.SetString("username", value); }
}
}
然后会话包装器被配置为 Startup.cs
内的范围服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
// ...
// Register the service we use for session handling.
services.AddScoped<SessionService>();
}
最后但同样重要的是,该服务被注入到我们的页面模型中,并用于通过其 属性.
访问会话
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
private readonly SessionService _session;
public IndexModel(ILogger<IndexModel> logger, SessionService session)
{
_logger = logger;
_session = session;
}
public void OnPost()
{
// Set the session variable.
_session.Username = "foo@bar";
}
}
我发布答案是希望获得对我的解决方案的反馈,并为其他遇到此问题的人提供参考点。
为了改进我们应用程序中的会话处理,我们想创建一个包装器 class,它通过属性管理会话访问(以防止在使用字符串时出现常见问题)。
像这样:
public class Wrapper
{
public string Username
{
get { return HttpContext.Current.Session.GetString("username"); }
set { HttpContext.Current.Session.SetString("username", value); }
}
}
在 classic ASP.Net 中有很多关于如何实现这一点的示例,但我们无法将它们移植到 ASP.Net Core。关于 ASP.Net Core 中的会话包装器(我能找到)的唯一 other question 是使用 Singleton,我们发现它不适合我们的情况。
我们的问题归结为两个主要问题:
- 如何正确包装和访问另一个 class 中的当前会话(避免反模式和安全问题)
- 如何在我们的应用程序中共享 class
我们决定使用 ASP.Net Core 的依赖注入功能,因为它看起来非常适合这项工作。要访问服务内的会话 IHttpContextAccessor is necessary. As stated in David Fowler's ASP.NET Core Diagnostic Scenarios it is recommended to not store the IHttpContextAccessor.HttpContext
in a field, however using a
我们的设置
这里我们使用HttpContextAccessor
来引用当前会话。通过使用属性限制对会话的访问(字符串可以进一步替换为常量)。
public class SessionService
{
private readonly ISession _session;
public SessionService(IHttpContextAccessor accessor)
{
_session = accessor.HttpContext.Session;
}
public string Username
{
get { return _session.GetString("username"); }
set { _session.SetString("username", value); }
}
}
然后会话包装器被配置为 Startup.cs
内的范围服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
// ...
// Register the service we use for session handling.
services.AddScoped<SessionService>();
}
最后但同样重要的是,该服务被注入到我们的页面模型中,并用于通过其 属性.
访问会话 public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
private readonly SessionService _session;
public IndexModel(ILogger<IndexModel> logger, SessionService session)
{
_logger = logger;
_session = session;
}
public void OnPost()
{
// Set the session variable.
_session.Username = "foo@bar";
}
}
我发布答案是希望获得对我的解决方案的反馈,并为其他遇到此问题的人提供参考点。