【问题标题】:Unable to serialize the session state... [Updated!]无法序列化会话状态... [更新!]
【发布时间】:2010-11-23 01:19:32
【问题描述】:

我试图在会话中存储一些对象(使用 StateServer),但我收到错误“System.Web.HttpException: Unable to serialize session state. In 'StateServer' and 'SQLServer' mode "

我知道错误消息的含义,但我不知道为什么。我使用的所有类都标记为可序列化,我可以使用以下方法对 XML 对象进行序列化和反序列化:

System.IO.StringReader stringReader = new System.IO.StringReader(xml);
System.Xml.XmlTextReader xmlTextReader = new System.Xml.XmlTextReader(stringReader);
System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(typeof(Parts));
Parts obj = ((Parts)(xmlSerializer.Deserialize(xmlTextReader)));

这可行,并且也将使用以下方法进行序列化:

System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(this.GetType());
System.IO.MemoryStream memoryStream = new System.IO.MemoryStream();
xmlSerializer.Serialize(memoryStream, this);
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
System.IO.StreamReader streamReader = new System.IO.StreamReader(memoryStream);
return streamReader.ReadToEnd();

但是尝试将其存储在 Session 中时会引发错误。

有没有人知道是什么导致了这种行为?

编辑:

我刚刚发现此行导致错误(已删除所有内容并重新包含它)

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("RecordReference", typeof(RecordReference), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]
[System.Xml.Serialization.XmlElementAttribute("PartContainer", typeof(PartContainer), Form = System.Xml.Schema.XmlSchemaForm.Unqualified, Order = 0)]
public object Item
{
    get
    {
        return this.itemField;
    }
    set
    {
        this.itemField = value;
    }
}

如果我将此“Item”属性设置为“new RecordReference()”,则会发生错误。如果为null,那就没问题了。

所以现在的问题是,为什么 StateServer 不能处理这个问题?序列化为 XML 时,它可以很好地序列化...

编辑...

程序集“System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”中的类型“System.Xml.XmlElement”未标记为可序列化。

.....我们是说 C# 中的 Xml 对象不可序列化?!有没有人认为这近乎疯狂?

【问题讨论】:

    标签: c# asp.net serialization


    【解决方案1】:

    在堆栈跟踪中,您应该会看到一个 SerializationException,它会提到它无法序列化的类...

    [SerializationException: Type 'SomethingOrOther' in Assembly 'SomethingElse' ...
    

    请注意,状态服务器使用二进制序列化而不是 XML 序列化。

    【讨论】:

    • 类型为:System.Runtime.Serialization.SerializationException: Type 'System.Xml.XmlNode' in Assembly 'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is未标记为可序列化。
    • 我知道 StateServer 使用二进制序列化 - 我们是说二进制序列化不能序列化“对象”类型的属性吗?
    • 我认为它不关心属性的类型,只关心碰巧分配给它的对象(所以当它为空时你很好)。我想我们是说二进制序列化无法处理 XmlNode。
    【解决方案2】:

    所以我找到了问题的答案,但我对此并不满意。

    基本上,我使用的一些类包含 XMLElements 和 XMLNodes(它们是使用 svcutil 自动生成的)。不管出于什么原因,但它认为它需要它们。

    这些 XML 类都不是可序列化的!!我是唯一一个认为这是这些物品完全失败的人吗?因此,要将这组类放入会话中,我必须将它们序列化为一个字符串,然后将其存储在会话中,会话依次对其进行序列化。所以我正在序列化它以便它被序列化......!?

    我不确定我是否对此感到满意,但这就是我遇到问题的原因。

    【讨论】:

    • 只是想说我发现你对这个问题的愤怒是有道理的(我同意你的观点)并且很有趣——当我读到它时,我脸上露出了微笑。大声笑
    • 刚刚遇到了同样的问题,有点有趣的是 XmlElement 是不可序列化的,因为它只是 XML 的容器。
    【解决方案3】:

    永远不要使用 InProc。它就像天气或室友按时支付租金一样可靠。你永远不知道它什么时候会退出。

    InProc 使用可用的 RAM 资源。如果机器需要 RAM 资源用于其他更优先的任务,它将被回收。所以会话信息可以持续 20 分钟或您设置的任何时间。或者当你期待 20 分钟时,它可能会持续 2 分钟。就像你永远不知道的天气一样。在机器不忙的开发中,这一切都很好。然后直播,人们从购物车中获得免费的东西,因为他们向 Paypal 收取 0 美元。

    如果您要使用 Session 信息,那么 State Server 是最简单、最轻松的方式。它也几乎是防弹的。我已经使用它多年,零问题。您可以重新构建您的应用程序,部署它,并且用户不会丢失会话信息并继续保持正常状态,就像什么都没发生过一样。另外,如果您使用 InProc,则不能在其他 Web 服务器中进行集群。您可以毫不费力地使用 StateServer,因为它就是为此而生的。至于非序列化的对象,只需将它们包装在一个对象中即可。例如,DataTables 是非序列化的,但 DataSet 是可序列化的。

    【讨论】:

    • 您可能会考虑编辑这篇文章以提高可读性。您的文字墙可能包含有用的信息,但很难阅读和区分您所说的内容。
    • 你有一些好的观点,但我不确定它们与使用状态服务器相关的问题有多相关?
    【解决方案4】:

    对于对象或复杂类,您需要在类中添加自己的序列化属性。

    所以对于 MyClass 做这样的事情

    [Serializable]
    public class MyClass : ISerializable
    {
    
       bool TorF=true;
       string str="Save me";
    
       public MyClass() {//need a constructor for your access}
    
      #region Serialisation
      //read in data
      public MyClass(SerializationInfo info, StreamingContext context)
      {
       TorF=(bool)info.GetValue("TorF",typeof(bool));
       str=(string)info.GetValue("str",typeof(string)); 
      }
    
      //write out data
      public void GetObjectData(SerializationInfo info, StreamingContext context)
      {
        info.AddValue("TorF", TorF);
        info.AddValue("str", str);
      }
    }
    

    【讨论】:

      【解决方案5】:

      最重要的是确保您的 web.config 将会话状态模式设置为“InProc”。根据您收到的错误消息,只需更改即可修复它。如果您仍然遇到问题,请确保将所有事件标记为不可序列化。

      【讨论】:

      • 我认为选择 StateServer 是经过深思熟虑的,因为 InProc 是默认设置。
      • 它是......改变它不是我害怕的选择
      【解决方案6】:

      正如 stevemegson 所说,找出哪个类抛出了 SerializationException。

      [SerializationException: Type 'SomethingOrOther' in Assembly 'SomethingElse' ...
      

      在您的代码中找到“SomethingOrOther”类并确保它是可序列化的。

      在 C# 中使类可序列化:

         [Serializable]_
            public class PayeeData
            {
               ...
            }
      

      在 VB.NET 中使类可序列化:

         <Serializable()> _
            Public Class PayeeData
               ...
            End Class
      

      有关 XML 序列化的具体查询,请参阅此 MSDN 文章:

      XML Serialization in the .NET Framework

      【讨论】:

        猜你喜欢
        • 2012-05-07
        • 2013-09-24
        • 2021-07-18
        • 1970-01-01
        • 2013-09-27
        相关资源
        最近更新 更多