- Home /
Why does deserialization fail in the web player
I’m running a C# script in Unity 4.0.0f7 and am trying to deserialize a simple class using the DataContractSerializer, but an exception is thrown when run in the Web Player from a browser. This works fine in the Unity editor or when built for PC/Mac platform. The error sounds like the constructor is not accessible, but there is a public, default constructor on the class. I’m guessing that this is some restriction for the Web Player, but the DataContractSerializer isn’t listed in Unity’s Mono Compatiblity list so I don’t know if it is allowed or not.
To use the DataContractSerializer, I copied the System.Runtime.Serialization.dll from the C:\\Program Files (x86)\\Unity\\Editor\\Data\\Mono\\lib\\mono\\unity directory to my Unity project’s Assets\\Plugins directory.
Ultimately, I am trying to deserialize an object that was serialized with the DataContractSerializer and obtained from a restful web service.
A similar question was asked some time ago, but no answer was ever posted.
Update: This problem does not appear to happen if using the XmlSerializer instead of the DataContractSerializer. I tested the same code with the XmlSerializer and it worked fine in the Web Player.
Here’s the code that is failing:
[DataContract]
public class Number
{
[DataMember]
public int Int1 { get; set; }
}
public class TalkRest : MonoBehaviour
{
void Start()
{
try
{
Number num = new Number();
num.Int1 = 1;
DataContractSerializer dcs = new DataContractSerializer(num.GetType());
using (var ms = new MemoryStream())
{
dcs.WriteObject(ms, num);
Debug.Log("Number serialized.");
ms.Position = 0;
Number resultNum = (Number) dcs.ReadObject(ms);
Debug.Log(resultNum);
}
}
catch (Exception e)
{
Debug.Log("DataContractSerializeTest exception: " + e.Message + ", stack: " + e.StackTrace);
}
}
private void Update() {}
}
Here’s the exception that is thrown:
DataContractSerializeTest exception: Attempt to access a private/protected method failed., stack: at System.Security.SecurityManager.ThrowException (System.Exception ex) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.SerializationMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer, Boolean empty) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.SerializationMap.DeserializeContent (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.SerializationMap.DeserializeObject (System.Xml.XmlReader reader, System.Runtime.Serialization.XmlFormatterDeserializer deserializer) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializeByMap (System.Xml.XmlQualifiedName name, System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.XmlFormatterDeserializer.DeserializeCore (System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Type type, System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.XmlFormatterDeserializer.Deserialize (System.Xml.XmlReader reader, System.Type type, System.Runtime.Serialization.KnownTypeCollection knownTypes, IDataContractSurrogate surrogate, System.String name, System.String ns, Boolean verifyObjectName) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.DataContractSerializer.ReadObject (System.Xml.XmlDictionaryReader reader, Boolean verifyObjectName) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.XmlObjectSerializer.ReadObject (System.Xml.XmlDictionaryReader reader) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.DataContractSerializer.ReadObject (System.Xml.XmlReader reader) [0x00000] in <filename unknown>:0
at System.Runtime.Serialization.XmlObjectSerializer.ReadObject (System.IO.Stream stream) [0x00000] in <filename unknown>:0
at TalkRest.Start () [0x00000] in <filename unknown>:0
Thanks in advance!
Answer by Alec Thilenius · Dec 19, 2012 at 07:56 PM
If I had to take a shot in the dark... I'm guessing its because Unity AOT compiles the scripts for web player, and AOT compilation for web does not support reflection, or something else that the Data Contract Serializer needs. When you AOT compile C# it gets turned into a binary, and the VM is no longer part of the equation. There is and always will be things you can not do with a AOT compiled library that you can do with a JIT compiled library. I'm guessing this works on PC because the scripts are being JIT compiled and run in a VM. This is a guess though, if someone has a better idea?
Webplayer builds aren't AOT compiled. You can load assemblies dynamically, even in the webplayer. I've done this already. The webplayer uses the exact same engine as a standalong build with the little difference that the mono environment runs in a sandbox with has some restrictions.
Since this exception is thrown by the security manager i'm pretty sure some part of the deserializer uses a class / a function that isn't allowed in the webplayer. See the $$anonymous$$onoCompatibility page what classes and what functions / properties of those classes are supported.
Thanks Bunny83 for the comment. It makes sense that the problem is a webplayer restriction, but the DataContractSerializer class isn't listed on the $$anonymous$$onoCompatiblity page, so it's guesswork to figure out what why the webplayer is restricting it.
Your answer
