Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何从ASP.NET中的任何类访问会话变量?_C#_Asp.net_Session Variables - Fatal编程技术网

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

C# 如何从ASP.NET中的任何类访问会话变量?,c#,asp.net,session-variables,C#,Asp.net,Session Variables,我在应用程序的App_Code文件夹中创建了一个类文件。我有一个会话变量 Session["loginId"] 我想在我的类中访问这个会话变量,但是当我写下面这行时,它给出了错误 Session["loginId"] 有人能告诉我如何访问在ASP.NET 2.0(C#)的app_code文件夹中创建的类中的会话变量吗通过线程的HttpContext访问会话:- HttpContext.Current.Session["loginId"] (为完整性而更新) 您可以使用s

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

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

Session["loginId"]

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

通过线程的HttpContext访问会话:-

HttpContext.Current.Session["loginId"]
(为完整性而更新)
您可以使用
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;
这种方法有几个优点:

  • 它为您节省了大量的类型转换
  • 您不必在整个应用程序中使用硬编码的会话密钥(例如会话[“loginId”]
  • 您可以通过在MySession属性上添加XML文档注释来记录会话项
  • 您可以使用默认值初始化会话变量(例如,确保它们不为null)

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

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

解释这是如何实现的:

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

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


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

建议的解决方案的问题是它可能会中断如果使用进程外会话存储,则会在会话状态中内置一些性能功能。(状态服务器模式或SQL Server模式)。在oop模式下,会话数据需要在页面请求结束时序列化,并在页面请求开始时反序列化,这可能会很昂贵。为了提高性能,SessionState尝试仅反序列化第一次访问时仅反序列化变量所需的内容,并且仅重新序列化并重新表示如果您有很多会话变量并将它们全部推到一个类中,会话中的所有内容将在使用会话的每个页请求中被反序列化,并且即使仅改变了1个属性,所有的内容都需要重新序列化。使用大量会话和oop模式。

我也有同样的错误,因为我试图在自定义会话类中操作会话变量

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


MA

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

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

}

在asp.net core中,此功能的工作方式不同:

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");
    }
}

来源:

无需编写任何代码,如答案所示使用。例如,“public int LoginId{get;set;}”-->这称为自动属性。如果您使用的是.net 3.x,则可以使用我的代码中所示的自动属性。对于.net 2.x/1.x,这是不可用的,您必须自己实现属性的getter/setter:private int\u loginId;public int loginId{get{return u loginId;}set{u loginId=value;}现在看起来很酷,我想我已经找到了问题的答案,我一直在用你的方式,它非常干净,而且很容易在一个地方维护我的所有会话变量。谢谢@Martin,你太棒了。@M4N,希望我能表达比a+1多一点的感激之情。这已经成为我在项目中处理会话/缓存的最喜欢的方式。我的代码,li谢谢。@Kristopher虽然'Current'属性是静态的,但MySession实例返回的不是…所以它很好。静态方法和属性可以安全地以这种方式使用。非常感谢Anthony完成了这个简单的步骤。非常感谢Anthony,+1谢谢。忘记了名称空间是什么:)@AnthonyWJones我使用了你的方法,但有问题,你能解释一下,我错在哪里,或者什么是正确的使用方法,我的问题,以及你是否想转换成HttpSessionStateBase:HttpSessionStateBase session=newHttpSessionStateWrapper(HttpContext.Current.session);re:这是一个很好的解释,它帮了我+1:)+1提出来。如果您没有在会话中使用InProc,则Ernie是100%正确的。InProc非常有限,因为它不支持webfarms,如果应用程序重新启动,它将丢失。请注意,按性能成本计算,在使用状态服务器模式时,我们预计会有20%的额外成本,此外还会增加序列化成本。正如你可以想象的那样,这可能会变得昂贵。通过坚持使用基本类型(例如int、string、char、b),可以避免一些序列化开销
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");
    }
}