如何在ASP.NET中的任何类中访问会话变量?
问题的原因是,如果在ASP.NET中使用了“State Server Mode”或“SQL Server Mode”这两种外部进程的会话存储方式,那么上述解决方案可能会破坏一些内置于SessionState中的性能特性。在这两种外部进程模式下,会话数据在页面请求结束时需要进行序列化,并在页面请求开始时进行反序列化,这可能会导致性能损耗。为了提高性能,SessionState会尝试只在第一次访问时反序列化所需的变量,并且只会重新序列化和替换已更改的变量。如果将大量的会话变量都放入一个类中,那么在每个使用会话的页面请求中,会话中的所有内容都将被反序列化,并且即使只有一个属性更改,也需要重新序列化整个类的内容。如果您使用了大量的会话变量并且使用oop模式,这是需要考虑的一点。
问题的解决方法是,如果未使用InProc作为会话存储方式,那么应该像Ernie所说的那样完全正确。InProc的功能非常有限,因为它不支持WebFarm,并且在应用程序重新启动时会丢失会话数据。需要注意的是,性能成本上我们在使用State Server模式时会有20%的额外开销,并且还需要额外的序列化成本。可以通过使用基本类型(例如int、string、char、byte等)来避免一些序列化开销。自定义对象将面临序列化的问题,用户要自行注意。
另外一种解决方法是,将自定义的“session”类中的每个属性调用ASP.NET会话本身,而不是将所有内容都放在一个大对象中存储在会话中。虽然这种方法需要进行类型转换,但如果每次只读取一部分会话数据,可能是值得的。
,解决这个问题的方法是,将会话变量尽量分散存储在多个类中,避免将所有内容都放在一个大对象中存储在会话中,以减少序列化和反序列化的性能损耗。
如何从ASP.NET中的任何类中访问会话变量?
问题的原因:在ASP.NET中,如果我们想要从任何类中访问会话变量,我们需要找到一种方法来获取当前线程的HttpContext,然后使用该HttpContext来访问会话变量。在这种情况下,问题的原因是作者忘记了HttpContext的命名空间。
解决方法:为了解决这个问题,我们可以使用HttpContext.Current.Session来访问会话变量。这个方法返回当前线程的HttpContext,然后我们可以使用这个HttpContext来访问会话变量。另外,如果我们想要将HttpContext转换为HttpSessionStateBase类型,我们可以使用HttpSessionStateWrapper类来实现。
以下是解决问题的代码示例:
// Access the Session via the thread's HttpContext string loginId = HttpContext.Current.Session["loginId"] as string; // Convert HttpContext to HttpSessionStateBase HttpSessionStateBase session = new HttpSessionStateWrapper(HttpContext.Current.Session);
感谢Anthony提供了这个简单的解决方法。
在ASP.NET中,我们可以通过Session["loginId"]
来访问会话变量。但是,如果我们想要从任何类(例如从类库中)访问会话变量,我们需要使用System.Web.HttpContext.Current.Session["loginId"]
。
为了简化对会话变量的访问,我通常会使用一个包装类来封装ASP.NET会话。这个类将自身的一个实例存储在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; }
}
这个封装类具有以下几个优点:
- 它可以避免大量的类型转换
- 您不需要在整个应用程序中使用硬编码的会话键(例如Session["loginId"])
- 您可以通过在MySession的属性上添加XML文档注释来对会话项进行文档化
- 您可以使用默认值初始化会话变量,确保它们不为null
通过这种封装类,您可以在任何类中以以下方式访问会话属性:
int loginId = MySession.Current.LoginId; string property1 = MySession.Current.Property1; MySession.Current.Property1 = newValue; DateTime myDate = MySession.Current.MyDate; MySession.Current.MyDate = DateTime.Now;
这种方法非常简洁和易于维护,我已经在我的项目中广泛使用它。希望这篇文章对您有所帮助。