【问题标题】:How to access session variables from any class in ASP.NET?如何从 ASP.NET 中的任何类访问会话变量?
【发布时间】:2010-10-11 21:58:28
【问题描述】:

我在我的应用程序的 App_Code 文件夹中创建了一个类文件。我有一个会话变量

Session["loginId"]

我想在我的班级中访问这个会话变量,但是当我写下面一行时,它给出了错误

Session["loginId"]

谁能告诉我如何访问在 ASP.NET 2.0 (C#) 的 app_code 文件夹中创建的类中的会话变量

【问题讨论】:

    标签: c# asp.net session-variables


    【解决方案1】:

    通过线程的HttpContext访问Session:-

    HttpContext.Current.Session["loginId"]
    

    【讨论】:

    • 非常感谢安东尼的这个简单步骤。
    • 非常感谢安东尼,+1
    • 谢谢。忘记命名空间是什么了:)
    • @AnthonyWJones 我用了你的方法,但是有问题,你能解释一下,我错在哪里或者什么是正确的使用方法,我的问题stackoverflow.com/questions/45254279/…
    • 如果你想转换为 HttpSessionStateBase: HttpSessionStateBase session = new HttpSessionStateWrapper(HttpContext.Current.Session);回复:stackoverflow.com/questions/5447611/…
    【解决方案2】:

    在 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/

    【讨论】:

      【解决方案3】:

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

      将以下类添加到您的 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;
      

      【讨论】:

        【解决方案4】:

        (为完整性而更新)
        您可以使用 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 cmets 来记录您的会话项目
        • 您可以使用默认值初始化会话变量(例如,确保它们不为空)

        【讨论】:

        • 无需编写任何代码,如答案所示使用。例如。 "public int LoginId { get; set; }" --> 这称为自动属性。
        • 如果您使用的是 .net 3.x,您可以使用自动属性,如我的代码所示。对于 .net 2.x/1.x,这是不可用的,您必须自己实现属性的 getter/setter:private int _loginId;公共 int LoginId { get { return _loginId; } 设置 { _loginId = 值; } }
        • 现在看起来很酷,我想我已经找到了我的问题的答案,而且我已经在使用您的方式,它非常干净且易于在一个地方维护我的所有会话变量。谢谢@Martin,你太棒了。
        • @M4N,希望我能比 +1 表达更多的感激之情。这已成为我在项目中处理会话/缓存的最喜欢的方式。从字面上看,我的代码是在感谢你。
        • @Kristopher 虽然“当前”属性是静态的,但返回的 MySession 实例不是……所以没关系。以这种方式使用静态方法和属性是安全的。
        【解决方案5】:

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

        我必须将当前上下文 (system.web.httpcontext.current) 传递给类,然后一切正常。

        MA

        【讨论】:

          【解决方案6】:

          建议的解决方案的问题是,如果您使用进程外会话存储,它可能会破坏 SessionState 中内置的一些性能特性。 (“状态服务器模式”或“SQL Server 模式”)。在 oop 模式下,会话数据需要在页面请求结束时进行序列化,并在页面请求开始时进行反序列化,这可能代价高昂。为了提高性能,SessionState 尝试仅在第一次访问时仅通过反序列化变量来反序列化所需的内容,并且仅重新序列化和替换已更改的变量。如果您有很多会话变量并将它们全部推到一个类中,那么基本上会话中的所有内容都将在使用会话的每个页面请求上反序列化,并且即使由于类更改而仅更改了 1 个属性,所有内容都需要再次序列化。如果您使用大量会话和 oop 模式,则需要考虑一些事情。

          【讨论】:

          • +1 来解决这个问题。如果您没有使用 InProc 进行 Session,那么 Ernie 是 100% 正确的。无论如何,InProc 非常有限,因为它不支持 webfarm,并且如果应用程序重新启动,它将丢失。请注意,通过性能成本,我们看到使用 State Server 模式有 20% 的溢价,并且在此基础上增加了序列化成本。正如您可以想象的那样,这可能会变得昂贵。您可以通过坚持原始类型(例如 int、string、char、byte 等)来避免一些序列化开销。自定义对象将面临序列化。用户小心。
          • +1 好点。将这两个概念结合在一起的更改是让这个自定义“会话”类上的每个属性都调用 asp.net 会话本身,而不是会话中的一个大对象。必须进行 @M4N 的方法避免的类型转换,但如果您每次只阅读一些会话,也许值得。
          【解决方案7】:

          我之前提出的答案为问题提供了恰当的解决方案,但是,我觉得理解为什么会导致此错误很重要:

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

          MSDN 解释了这是怎么可能的:

          由于 ASP.NET 页面包含对 System.Web 命名空间(其中包含 HttpContext 类)的默认引用,因此您可以在 .aspx 页面上引用 HttpContext 的成员,而无需完全限定类引用 @ 987654329@.

          但是,当您尝试在 App_Code 中的类中访问此属性时,除非您的类派生自 Page Class,否则您将无法使用该属性。

          我对这种经常遇到的情况的解决方案是我从不将页面对象传递给类。我宁愿从页面Session中提取需要的对象,并以名值集合/数组/列表的形式传递给Class,视情况而定。

          【讨论】:

          • 这是一个很好的解释,它帮助我 +1 :)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-06-09
          • 2011-11-25
          • 2014-03-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多