如何从 ASP.NET 中的任何类访问会话变量?

我已经在应用程序的 App _ Code 文件夹中创建了一个类文件

Session["loginId"]

我想在我的类中访问这个会话变量,但是当我写下一行时,它会出错

Session["loginId"]

有人能告诉我如何访问在 ASP.NET 2.0(C #)的 app _ code 文件夹中创建的类中的会话变量吗

347138 次浏览

通过线程的 HttpContext 访问会话:-

HttpContext.Current.Session["loginId"]

(更新为完整版)
您可以使用 Session["loginId"]从任何页面或控件访问会话变量,也可以使用 System.Web.HttpContext.Current.Session["loginId"].从任何类(例如从类库内部)访问会话变量

但请继续读我的原始答案..。


我总是在 ASP.NET 会话周围使用一个包装类来简化对会话变量的访问:

public class MySession
{
// private constructor
private MySession()
{
Property1 = "default value";
}


// Gets the current session.
public static MySession Current
{
get
{
MySession session =
(MySession)HttpContext.Current.Session["__MySession__"];
if (session == null)
{
session = new MySession();
HttpContext.Current.Session["__MySession__"] = session;
}
return session;
}
}


// **** add your session properties here, e.g like this:
public string Property1 { get; set; }
public DateTime MyDate { get; set; }
public int LoginId { get; set; }
}

这个类在 ASP.NET 会话中存储它自己的一个实例,并允许您以类型安全的方式从任何类访问会话属性,例如:

int loginId = MySession.Current.LoginId;


string property1 = MySession.Current.Property1;
MySession.Current.Property1 = newValue;


DateTime myDate = MySession.Current.MyDate;
MySession.Current.MyDate = DateTime.Now;

这种方法有几个好处:

  • 这样就省去了很多打字的麻烦
  • 您不必在整个应用程序中使用硬编码的会话密钥(例如 Session [“ loginId”])
  • 您可以通过在 MySession 的属性上添加 XML doc 注释来记录会话项
  • 您可以使用默认值初始化会话变量(例如,确保它们不为空)

我面前的答案为这个问题提供了恰当的解决办法,然而,我认为理解这个错误的原因很重要:

PageSession属性返回与该特定请求相关的 HttpSessionState类型的实例。Page.Session实际上等同于调用 Page.Context.Session

MSDN 解释了这种可能性:

因为 ASP.NET 页包含对系统的默认引用。Web 命名空间(其中包含 HttpContext类) ,可以在。Aspx 页面,但没有对 HttpContext的完全限定类引用。

但是,当您尝试在 App _ Code 中的类中访问此属性时,除非您的类从 Page Class 派生,否则该属性将不可用。

对于这种经常遇到的情况,我的解决方案是 我从不向类传递页对象。我更愿意从 Session 页面提取所需的对象,并根据具体情况以名称-值集合/Array/List 的形式将它们传递给 Class。

所建议的解决方案的问题在于,如果您使用进程外会话存储,它可能会破坏 SessionState 中内置的一些性能特性。(“状态服务器模式”或“ SQLServer 模式”)。在 OP 模式下,会话数据需要在页面请求的末尾进行序列化,并在页面请求的开头进行反序列化,这样做的开销很大。为了提高性能,SessionState 尝试在第一次访问变量时只反序列化变量所需的内容,并且只重新序列化和替换已更改的变量。如果你有很多会话变量,并把它们全部放到一个类中,基本上每个使用会话的页面请求中会话中的所有内容都会被反序列化,所有内容都需要再次序列化,即使只有一个属性因为类的改变而改变。只是一些东西要考虑,如果你使用会话和一个运行模式很多。

我也有同样的错误,因为我试图在自定义 Session 类中操作会话变量。

我必须将当前上下文(system.web.httpcontext.current)传递到类中,然后一切都很好。

这对于应用程序和开发人员来说都应该更有效率。

将以下类添加到您的 Web 项目中:

/// <summary>
/// This holds all of the session variables for the site.
/// </summary>
public class SessionCentralized
{
protected internal static void Save<T>(string sessionName, T value)
{
HttpContext.Current.Session[sessionName] = value;
}


protected internal static T Get<T>(string sessionName)
{
return (T)HttpContext.Current.Session[sessionName];
}


public static int? WhatEverSessionVariableYouWantToHold
{
get
{
return Get<int?>(nameof(WhatEverSessionVariableYouWantToHold));
}
set
{
Save(nameof(WhatEverSessionVariableYouWantToHold), value);
}
}


}

以下是实施方案:

SessionCentralized.WhatEverSessionVariableYouWantToHold = id;

在 asp.net 核心中,这种方法的工作原理是不同的:

public class SomeOtherClass
{
private readonly IHttpContextAccessor _httpContextAccessor;
private ISession _session => _httpContextAccessor.HttpContext.Session;


public SomeOtherClass(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}


public void TestSet()
{
_session.SetString("Test", "Ben Rules!");
}


public void TestGet()
{
var message = _session.GetString("Test");
}
}

资料来源: https://benjii.me/2016/07/using-sessions-and-httpcontext-in-aspnetcore-and-mvc-core/