How to access session variables from any class in ASP.NET?
我在应用程序的App_Code文件夹中创建了一个类文件。 我有一个会话变量
1 | Session["loginId"] |
我想在我的类中访问此会话变量,但是当我编写以下行时,它会给出错误
1 | Session["loginId"] |
任何人都可以告诉我如何访问在ASP.NET 2.0(C#)中的app_code文件夹中创建的类中的会话变量
(为完整性而更新)
您可以使用
但请继续阅读我的原始答案......
我总是在ASP.NET会话周围使用包装类来简化对会话变量的访问:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 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会话中存储自身的一个实例,并允许您以类型安全的方式从任何类访问会话属性,例如:
1 2 3 4 5 6 7 | 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注释来记录会话项
- 您可以使用默认值初始化会话变量(例如,确保它们不为空)
通过线程HttpContext访问Session: -
1 | HttpContext.Current.Session["loginId"] |
建议的解决方案的问题是,如果您使用进程外会话存储,它可能会破坏SessionState中内置的一些性能功能。 ("状态服务器模式"或"SQL Server模式")。在oop模式中,会话数据需要在页面请求结束时序列化,并在页面请求开始时反序列化,这可能是昂贵的。为了提高性能,SessionState尝试仅在第一次访问变量时仅对反序列化变量进行反序列化,并且只重新序列化并替换已更改的变量。如果您有很多会话变量并将它们全部推送到一个类中,那么会话中的所有内容都将在每个使用会话的页面请求上反序列化,即使只更改了1个属性,所有内容也需要再次序列化。如果您使用大量会话和oop模式,只需要考虑一些事情。
我之前提出的答案提供了解决问题的方法,但是,我觉得理解为什么会出现这个错误很重要:
MSDN解释了这是如何可能的:
Because ASP.NET pages contain a default reference to the System.Web namespace (which contains the
HttpContext class), you can reference the members ofHttpContext on an .aspx page without the fully qualified class reference toHttpContext .
但是,当您尝试在App_Code中的类中访问此属性时,除非您的类派生自Page类,否则该属性将不可用。
我对这种经常遇到的场景的解决方案是我从不将页面对象传递给类。我宁愿从页面Session中提取所需的对象,并以名称 - 值集合/ Array / List的形式将它们传递给Class,具体取决于具体情况。
我有同样的错误,因为我试图在自定义Session类中操作会话变量。
我必须将当前上下文(system.web.httpcontext.current)传递给类,然后一切都很好。
嘛
在asp.net核心中,这种方式不同:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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/
这应该对应用程序和开发人员都更有效。
将以下类添加到Web项目中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /// <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); } } } |
这是实施:
1 | SessionCentralized.WhatEverSessionVariableYouWantToHold = id; |