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

时间:2009-03-07 08:48:43

标签: c# asp.net session-variables

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

Session["loginId"]

我想在我的类中访问此会话变量,但是当我编写以下行时,它会给出错误

Session["loginId"]

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

7 个答案:

答案 0 :(得分:349)

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

答案 1 :(得分:100)

通过线程HttpContext访问Session: -

HttpContext.Current.Session["loginId"]

答案 2 :(得分:22)

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

答案 3 :(得分:12)

我之前提供的答案为问题提供了合适的解决方案,但是,我觉得理解为什么会出现这种错误很重要:

Session的{​​{1}}属性返回相对于该特定请求的类型Page的实例。 HttpSessionState实际上相当于调用Page.Session

MSDN解释了这是如何可能的:

  

由于ASP.NET页面包含对System.Web命名空间(包含Page.Context.Session类)的默认引用,因此您可以在.aspx页面上引用HttpContext的成员而不具有完全限定类引用HttpContext

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

我对这种经常遇到的情况的解决方案是我从不将页面对象传递给类。我宁愿从页面Session中提取所需的对象,并以name-value collection / Array / List的形式将它们传递给Class,具体取决于具体情况。

答案 4 :(得分:1)

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

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

MA

答案 5 :(得分: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;

答案 6 :(得分:0)

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