无法序列化会话状态... [已更新!]

时间:2009-08-26 15:10:27

标签: c# asp.net serialization

我试图在会话中存储一些对象(使用StateServer),但是我收到错误“System.Web.HttpException:无法序列化会话状态。在'StateServer'和'SQLServer'模式下“

我知道错误信息的含义,但我找不到原因。我正在使用的所有类都标记为Serializable,我可以使用以下命令对对象进行序列化和反序列化:

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时序列化很好......

修改...

在Assembly'System.Xml,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'中键入'System.Xml.XmlElement'未标记为可序列化。

.....我们是说C#中的Xml对象不可序列化?!还有其他人认为这是疯了吗?

6 个答案:

答案 0 :(得分:9)

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

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

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

答案 1 :(得分:6)

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

基本上,我正在使用的一些类包含XMLElements和XMLNodes(它们是使用svcutil自动生成的)。无论出于何种原因,它认为它需要它们。

这些XML类都不是可序列化的!我是唯一一个发现这完全失败的人吗?因此,为了将这组类添加到会话中,我必须将它们序列化为一个字符串,然后将其存储在会话中,然后将其序列化。所以我将它序列化以便序列化.....!?

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

答案 2 :(得分:4)

不要使用InProc。它和天气一样可靠,或者房间的伴侣按时支付租金。你永远都不知道什么时候会退出。

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

如果您要使用会话信息,那么State Server是最简单,最无痛的方式。它几乎也是防弹。我已经使用它多年没有问题。您可以重建您的应用程序,部署它,用户不会丢失会话信息,并保持正常状态。此外,如果您使用的是InProc,则无法在其他Web服务器中进行群集。你可以使用StateServer没有麻烦,因为它是为此而制作的。对于非serializabe的对象,只需将它们包装在一个对象中即可。例如,DataTables是非序列化的,但DataSet是可序列化的。

答案 3 :(得分:3)

对于对象或复杂类,则需要在类中添加自己的serialision属性。

所以对于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);
  }
}

答案 4 :(得分:-1)

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

答案 5 :(得分:-1)

正如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