I am trying to serialize and deserialize an object in c# unity3d. For that I am using the below code. But I am getting an error mentioned below.
Error: SerializationException: Could not find type 'System.Collections.Generic.List`1[[ABC, Assembly-CSharp, Version=1.0.2.18931, Culture=neutral, PublicKeyToken=null]]'.
This is not happening while I serialize the object save to file and load it from file while I am playing the game with out stopping the game.
But the error occurs if I stop the game and change any line of code ( irrelevant to serialization and Deserialization )and load data from file saved previously and trying to deserialize I am getting an SerializationException
.
I am using visual studio editor and unity3d version is 5.5.4
I may be missing something very simple thing. could someone help me in resolving this.
Thanks.
public static string SerializeObject<T>(T objectToSerialize) { BinaryFormatter bf = new BinaryFormatter(); MemoryStream memStr = new MemoryStream(); try { bf.Serialize(memStr, objectToSerialize); memStr.Position = 0; return Convert.ToBase64String(memStr.ToArray()); } finally { memStr.Close(); } } public static T DeserializeObject<T>(string str) { BinaryFormatter bf = new BinaryFormatter(); bf.Binder = new CurrentAssemblyDeserializationBinder(); byte[] b = Convert.FromBase64String(str); MemoryStream ms = new MemoryStream(b); try { return (T)bf.Deserialize(ms); } finally { ms.Close(); } }
Class I am using:
[Serializable] public class ABC : ISerializable { public SerializableDictionary<int, ExampleClass> a = new SerializableDictionary<int, ExampleClass>(); public GameObject b; public GameObject c; public bool d = false; public ABC e; public int f; public string g = ""; public int h = -1; public int i = -1; public int j = -1; public string k = "default"; public XYZ l = XYZ.P; } [Serializable] public enum XYZ { P, Q } [Serializable()] public class ABCListWrapper : ISerializable { public List<ABC> abcMappings = new List<ABC>(); public string version = "1.53"; public float interval; } //Serilization abcLW = new ABCListWrapper(); abcW = getABCListWObj(); string abcWString = SerializeObject(abcW); File.WriteAllText(Application.streamingAssetsPath + "/filename.json", abcWString); //Deserilization call ABCListWrapper l = new ABCListWrapper(); string l_1 = File.ReadAllText(Application.streamingAssetsPath + "/filename.json"); l = DeserializeObject<ABCListWrapper>(l_1);
Attempt to resolve the issue:
public sealed class CurrentAssemblyDeserializationBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { Version assemVer1 = Assembly.GetExecutingAssembly().GetName().Version; Debug.Log("ASSEM VER: " + assemVer1 + "--NAME--" + assemblyName + " --OVERAL-- " + Assembly.GetExecutingAssembly().FullName + " --TYPE-- " + typeName ); //assemblyName = Assembly.GetExecutingAssembly().FullName.Replace(assemVer1.ToString(), "1.0.2.23455"); //string assemblyNameCustom = "Assembly-CSharp, Version=1.0.2.18931, Culture=neutral, PublicKeyToken=null"; bool isList = false; if (typeName.Contains("List`1")) isList = true; // other generics need to go here if (isList) return Type.GetType(string.Format("System.Collections.Generic.List`1[[{0}, {1}]]", "ABC", "Assembly-CSharp, Version=1.0.2.18931, Culture=neutral, PublicKeyToken=null")); else return Type.GetType(string.Format("{0}, {1}", assemblyName, typeName)); } }
But I am getting the same exception and the log in BindToType
is never printed. So it means the function BindToType
in the SerilizationBinder
.
2 Answers
Answers 1
The binary formatter is storing the assembly version information along with the serialized type. So even when the type is not changed, the serialization/deserialization changes as soon as the assembly is updated.
See this related Q/A for details: Binary Deserialization with different assembly version and the relevant MSDN article.
Normally I would close-vote this as a duplicate, but I can't because of the open bounty, so I decided to answer instead ;)
Answers 2
For fast binary serialization Protocol Buffers can be good option. Also it should resolve compatibility issues (you can control fields order/exclusion manually)
0 comments:
Post a Comment