【问题标题】:Accessing properties of object stored in session访问存储在会话中的对象的属性
【发布时间】:2013-07-31 18:10:59
【问题描述】:

我一定对会话有误解。我正在尝试存储一些信息,所以让我提供详细信息。

这是我的“容器”类,它包含一个业务对象列表。此容器存储在会话中。

public class MySessionContainer {
    private IList<SomeBusinessObjectType> _BusinessObjectList = new List<SomeBusinessObjectType>();
    public IList<SomeBusinessObjectType> BusinessObjectList {
        get { return _BusinessObjectList; }
        set { _BusinessObjectList = value; }
    }
}

我有一组形成向导/多步骤流程的页面,它们都需要访问处于会话中的容器中的业务对象列表。

第一页将业务对象添加到会话中的列表中,因此使用这种代码来实现:

string key = GetKeyForCurrentUser();
MySessionContainer container = (MySessionContainer) Session[key];

SomeBusinessObjectType businessObject = /* Get object from view. */;

container.BusinessObjectList.Add(businessObject);

生成的密钥在所有页面中始终相同。

但是,当用户进入第二页时,容器按预期处于会话中,但业务对象列表为空,这不是我所期望的。如果第一个页面添加了一个业务对象,那么它应该在第二个页面和后续页面中......对吗?

关于 ASP.net 中的会话,我有什么不明白的地方吗?为什么容器在会话中而不是列表? ASP.net从会话中写入/读取时,列表是否没有与容器对象序列化?

【问题讨论】:

  • 你有没有试过修改后把它塞回Session?
  • @JerKimball 我已经考虑过了,但我认为在单个请求中,会话中的值始终是相同的引用。
  • 我必须检查一些东西才能确定(离开 asp.net 有一段时间了),但我的直觉是你在访问时得到了反序列化的副本,而不是原始参考。
  • 如果你的会话不是“inproc”,你必须确保你的整个对象图是可序列化的。

标签: c# asp.net session


【解决方案1】:

您需要将其写回会话。

看一下会话变量下的例子:

// When retrieving an object from session state, cast it to 
// the appropriate type.
ArrayList stockPicks = (ArrayList)Session["StockPicks"];

// Write the modified stock picks list back to session state.
Session["StockPicks"] = stockPicks;

ASP Session State Overview

【讨论】:

  • string 和 ArrayList 的原因是因为它们不能被引用更新。字符串是不可变的,而 ArrayList 是值类型。但是,MySessionContainerList&lt;&gt; 是引用类型。因此,它们不需要“写回会话”。
  • 这就是问题所在。不知道为什么我以前对这个事实完全心不在焉。
【解决方案2】:

会话对象不会在不同的用户之间共享,因此 GetKeyForCurrentUser 是无用的。您可以使用一些简单的字符串作为键。存储在 Session 中的对象必须是可序列化的,因此 SomeBusinessObjectType 也必须是可序列化的。

【讨论】:

  • 关于 GetKeyForCurrentUser 的要点。 SomeBusinessObject 类型被标记为可序列化。我认为根本问题是我没有将其写回会话。
  • 啊是的。我使用 Session 是很久以前的事了。他们应该为它的操作提供更直观的名称和方法。
【解决方案3】:

序列化对象图时,初始化程序可能会出现意外行为。如果您不想从父类中初始化集合,请尝试使用延迟加载的属性:

public class MySessionContainer {
    private IList<SomeBusinessObjectType> _BusinessObjectList;
    public IList<SomeBusinessObjectType> BusinessObjectList {
        get { return (_BusinessObjectList ?? 
                  (_BusinessObjectList = new List<SomeBusinessObjectType>()) ; }
        set { _BusinessObjectList = value; }
    }
}

这将允许反序列化设置您的列表,并且任何 getter 将永远不会为您的集合获取空值。

另外,确保图中的每个对象都可以序列化。请参阅here 了解更多信息。

This question 也可能与您的相关。

【讨论】:

    猜你喜欢
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    相关资源
    最近更新 更多