165

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

Session["loginId"]

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

Session["loginId"]

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

4

7 回答 7

373

(为完整性而更新)您可以从任何页面或控件使用和从任何类(例如,从类库内部)
访问会话变量,使用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 文档注释来记录您的会话项目
  • 您可以使用默认值初始化会话变量(例如,确保它们不为空)
于 2009-03-07T10:10:22.647 回答
108

通过线程的 HttpContext 访问 Session:-

HttpContext.Current.Session["loginId"]
于 2009-03-07T08:50:37.567 回答
24

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

于 2010-06-10T17:42:14.830 回答
12

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

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

MSDN解释了这是如何实现的:

因为 ASP.NET 页面包含对 System.Web 命名空间(包含类)的默认引用,所以您可以在没有完全限定的类引用的情况下引用 .aspx 页面上HttpContext的成员。HttpContextHttpContext

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

对于这种经常遇到的情况,我的解决方案是我从不将页面对象传递给 classes。我宁愿从页面 Session 中提取所需的对象,并根据情况以名称-值集合/数组/列表的形式将它们传递给 Class。

于 2009-03-07T11:28:53.503 回答
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/

于 2019-01-30T16:22:47.510 回答
1

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

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

于 2012-02-12T22:47:56.690 回答
0

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

将以下类添加到您的 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;
于 2018-04-19T22:46:20.017 回答