I am trying to store some objects in the session (which is using a StateServer), but I am getting the error "System.Web.HttpException: Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode"
I know what the error message means, but I can't work out why. All of the classes I am using are marked as Serializable, and I am able to Serialize and Deserialize the object to and from XML using:
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)));
This works, and will Serialize as well using:
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();
But the error is thrown when trying to store it in the Session.
Does anyone have any ideas what may be causing this behaviour?
EDIT:
I have just discovered that this line is causing the error (having removed everything and re-included it)
/// <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;
}
}
If I set this "Item" property to "new RecordReference()", then the error occurs. If it is null, it's fine.
So now, the question is, why can't the StateServer cope with this? It serializes fine when serializing to XML...
EDIT...
Type 'System.Xml.XmlElement' in Assembly 'System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable.
.....Are we saying that the Xml objects in C# aren't serializable?! Does anyone else think this verges on the insane?
In the stack trace you should see a SerializationException that will mention which class it's unable to serialize...
[SerializationException: Type 'SomethingOrOther' in Assembly 'SomethingElse' ...
Note that the state server uses binary serialization not XML serialization.
So I have found the answer to the question, but I'm not happy about it.
Basically, some of the classes I'm using contain XMLElements and XMLNodes (they're automatically generated using svcutil). For whatever reason, but it thinks it needs them.
Neither of these XML classes are serializable!! Am I the only one who finds this to be a complete failing of these objects? So to get this set of classes into the session, I've got to serialize them down to a string, and then store that in the session, which is in turn serializing it. So I'm serializing it in order for it to be serialized.....!?
Not sure I'm happy with that, but that was the cause of my problems.
Don't use ever use InProc. It is as reliable as the weather or a room mate paying their share of the rent on time. You never know when it is going to just drop out.
InProc uses available RAM resources. It will get recycled if the machine needs the RAM resources for other tasks of more priority. So the session info could last the 20 minutes or what ever you set it for. Or it could last 2 minutes when you're expecting 20. Just like the weather you never know. It all works great in Dev where the machine is not busy. Then live, people are getting free stuff off the shopping cart because they are being charged 0 dollars to Paypal.
If you are going to use Session information then State Server is the easiest and most pain free way. It is almost bullet proof also. I have used it for years with zero issues. You can rebuild your app, deploy it and the users don't loose the session info and keep right on like nothing ever happened. Plus you can't cluster in other web servers if you are using InProc. You can with StateServer with no hassle because it is made for that. As far as objects being non serializabe, just wrap them in an object that is. For instance DataTables are non-serializabe but a DataSet is serializable.
for objects or a complex class then you need to add in you own serialision attributes to the class.
So for MyClass do something like this
[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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With