在 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,我们发现它不适合我们的情况。

我们的问题归结为两个主要问题:

我们决定使用 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";
    }
  }

我发布答案是希望获得对我的解决方案的反馈,并为其他遇到此问题的人提供参考点。