当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何从ASP.NET中的任何类访问会话变量?》经验,为你挑选了4个好方法。

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

Session["loginId"]

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

Session["loginId"]

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



1> M4N..:

(为了完整性而更新)
您可以使用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注释来记录会话项

您可以使用默认值初始化会话变量(例如,确保它们不为空)


@ M4N,希望我能表达比+1更多的感激之情.这已成为我在项目中处理会话/缓存的最佳方式.从字面上看,我的代码感谢你.
无需编写任何代码,请按答案中的说明使用.例如"public int LoginId {get; set;}" - >这称为自动属性.
如果您使用的是.net 3.x,则可以使用我的代码中所示的自动属性.使用.net 2.x/1.x这是不可用的,您必须自己实现属性的getter/setter:private int _loginId; public int LoginId {get {return _loginId; } set {_loginId = value; }}
@Kristopher而'Current'属性是静态的,MySession返回的实例不是......所以没关系.以这种方式使用静态**方法和属性**是安全的.
现在看起来很酷,我想我得到了我的问题的答案,我用你的方式alreday,它非常干净,很容易在一个地方维护我的所有会话变量.谢谢@Martin,你真棒.
@ M4N,如果需要在proc会话存储中使用,你不会将该类标记为`[Serializable()]`吗?

2> AnthonyWJone..:

通过线程HttpContext访问Session: -

HttpContext.Current.Session["loginId"]



3> 小智..:

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


为此提供+1.如果您没有使用InProc进行会话,那么Ernie是100%正确的.无论如何,InProc非常有限,因为它不支持webfarms,如果应用程序重新启动将丢失.请注意,根据性能成本,我们在使用State Server模式时会看到20%的溢价,并且在此基础上添加了序列化成本.你可以想象这会变得昂贵.您可以通过坚持原始类型(例如int,string,char,byte等)来避免一些序列化开销.自定义对象将面临序列化.用户要小心.

4> Cerebrus..:

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

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

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

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

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

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

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有