【问题标题】:How to get session value in class anywhere?如何在课堂上随时随地获得会话价值?
【发布时间】:2015-06-04 14:30:36
【问题描述】:

我在 ASP.net 中有一些会话如下。在文件 Test.aspx.cs 中有一些会话

 HttpContext.Current.Session["Id"] = obj.USER_MOD_ID;
 HttpContext.Current.Session["Group"] = obj.GROUP_MOD_ID;
 HttpContext.Current.Session["Region"] = obj.REGION_ID;

然后我创建了一些类,我想获得会话的价值。

首先,我创建一个类 MySession.cs

 public class MySession
    {
        // private constructor
        private MySession()
        {
            value_group = "Group";
            //value_id = "Id";
            //value_region = "Region";
        }
        // Gets the current session.
        public static MySession Current
        {
            get
            {
                MySession session =(MySession)HttpContext.Current.Session["Group"];
                if (session == null)
                {
                    session = new MySession();
                    HttpContext.Current.Session["Group"] = session;
                }
                return session;
            }
        }
        // **** add your session properties here, e.g like this:
        public string value_group { get; set; }
        //public string value_id { get; set; }
        //public string value_region { get; set; }
    }

其次,我创建类 Test.cs 并且我想要获取会话的值

 string value_group = MySession.Current.value_group.ToString();
                //string value_id = MySession.Current.value_id.ToString();
                //string value_region = MySession.Current.value_region.ToString();

但是出错了

Object reference not set to an instance of an object 

谢谢大家。

【问题讨论】:

  • 为什么要将MySession 分配给您的HttpContext.Current.Session["Group"]?您之前已经在其中设置了值,并且想要访问它。或者你没有?请描述一下你要在那里存储什么,obj.GROUP_MOD_ID 是什么(是字符串)?
  • @YeldarKurmangaliyev 代码看起来有些合理 - 围绕访问会话值的包装类 - 不确定为什么您发现该代码错误。我的猜测有 97% 的可能性 - OP 尝试在请求之外访问 HttpContext.Current(即在某些单元测试代码中)。
  • @AlexeiLevenkov 也许,我就是不明白。这就是为什么我问他一个问题。至于我,value_group 现在是从常量值“Group”分配的,MySession 正在覆盖以前设置的 obj.GROUP_MOD_ID 值。我可能错了,但这不是会话值包装器的编写方式:)
  • @YeldarKurmangaliyev 我看到了 - 可能将 OP 复制粘贴到随机样本中......看起来像是将 3 个字段打包到单个对象中并在会话状态中使用一个键来存储它的合理方法,但可能是您阅读了 OP 希望通过包装器从会话状态中读取单个值的帖子(Current.value_region 以将 ...Session["region"] 转换为其类型...不清楚。
  • @YeldarKurmangaliyev 正是,正如 Alexei Levenkov 所说。你能给我一些建议吗?

标签: c# asp.net session


【解决方案1】:

正如您在 cmets 中所说,您需要为您的 Session 提供一个包装类。

以下是您可以轻松实现它的方法。我尽量按照你写的最多的代码:

public class MySession
{
    private const string GroupKey = "Group";
    private const string RegionKey = "Region";
    private const string IDKey = "Id";

    private static MySession _session;  
    public static MySession Current
    {
        get
        {
            return _session ?? (_session = new MySession());
        }
    }

    public string Group 
    { 
        get
        {
            return HttpContext.Current.Session[GroupKey] as string;
        }
        set
        {
            HttpContext.Current.Session[GroupKey] = value;
        }
    }

    public string Region
    {
        get
        {
            return HttpContext.Current.Session[RegionKey] as string;
        }
        set
        {
            HttpContext.Current.Session[RegionKey] = value;
        }
    }

    public string ID
    {
        get
        {
            return HttpContext.Current.Session[IDKey] as string;
        }
        set
        {
            HttpContext.Current.Session[IDKey] = value;
        }
    }
}

但是,您可能不需要它。您只使用一个当前的HttpContext.Current.Session。这些值是动态更改的,我猜你想要获取实际数据。因此,您的包装类可以是静态包装类。

public static class SessionWrapper
{
    private const string GroupKey = "Group";
    private const string RegionKey = "Region";
    private const string IDKey = "Id";

    public static string Group 
    { 
        get
        {
            return HttpContext.Current.Session[GroupKey] as string;
        }
        set
        {
            HttpContext.Current.Session[GroupKey] = value;
        }
    }

    public static string Region
    {
        get
        {
            return HttpContext.Current.Session[RegionKey] as string;
        }
        set
        {
            HttpContext.Current.Session[RegionKey] = value;
        }
    }

    public static string ID
    {
        get
        {
            return HttpContext.Current.Session[IDKey] as string;
        }
        set
        {
            HttpContext.Current.Session[IDKey] = value;
        }
    }
}

此外,它也不正确。我不会这样做,因为您要为每个会话属性描述一个键、getter 和 setter。如果您在会话中添加新属性(例如,'Language'),您将需要显着更改您的 MySession 类,这违反了 OCP 原则。

【讨论】:

  • 亲爱的@Yeldar,我尝试了你的代码,但它不起作用。在return HttpContext.Current.Session[GroupKey] as string;调试并显示错误Object reference not set to an instance of an object
  • Alexey Levenkov 可能是对的。您是否尝试在 HTTP 上下文之外使用此类?看起来您的 HttpContext.Current 为空。
  • 是的,请阅读我上面的步骤。在这里,我想在其他类中获取值会话,但仍然出现错误,会话是在 Test.aspx.cs 文件的类下创建的。然后我想获取会话的值并用在其他类中,一个全新的类。比如类 ABC.cs , XYZ.cs ,.etc...
  • 亲爱的@Yaldar,我有一个页面 Login.aspx ,在类 Login.aspx.cs 中,我创建了 session["Id"] 持有 user_id, session["User"] 持有 user_name, session[ "Group"] 持有 user_group,它的工作。现在我创建了一个新类,而不是继承页面,例如类 ABC.cs ,在类 ABC.cs 中,我想调用和使用 session["Id"], session["Group"], ...等的值。 .但我不知道。谢谢先生。
  • @Headshot Session 是 ASP.NET HttpContext 的一部分。它属于网络用户和会话。这意味着您只能在 ASP.NET 请求期间访问它。如果您不通过网络服务调用它,则当前的HttpContext 将为空。但是,如果您从 Controller 调用类 ABC,那么它也可以正常工作。