Issue with BinaryFormatter/FileStream and casting?

Hello, I’m currently trying the new experimental runtime and ran into an issue with this code:

var bf = new BinaryFormatter();
var stream = File.Open(path, FileMode.Open);
var saveTemp = (T)bf.Deserialize(stream); //System.InvalidCastException: Object must implement IConvertible
stream.Close();
return saveTemp;

The same code is working perfectly with the old runtime.
Is there non-backward compatible changes ?

Thanks !

This looks like a bug with the new class libraries. To be sure though, can you try this same code in standalone .NET on Windows? If it works there, it should work in Unity. Please file a bug in that case.

I’m sorry I’m using OSX and don’t have any Windows nearby to test.

Ok, please submit a bug report then, we will investigate this.

Done! Issue #932359
Thanks

2 Likes

I’ve got same issue. Is there any progress? :frowning:

Unfortunately no, we were not able to reproduce the issue based on the bug report provided earlier. If you have a project where this happens, please submit a bug report which includes that project, and we will investigate it.

Hey i have a similar issue
we have a project running unity 2018.3.6 and scripting runtime 3.5

upgraded the engine to unity 2019.1.7f1 and scripting runtime 4.x

we pushed the new update to our users and their save data is gone because of this…
if i try to read an old data file saved using scripting runtime 3.5 ,i get this error
but it works on subsequent saves…

is there anything we can do?

I’m not sure if the BinaryFormatter serialized version is stable across the .NET Versions. If you have a reproducible test case we can take a look at this in a bug report.

In the short term though, you may need to look at the serialized data from the old scripting runtime and see if you can convert it to the serialized format the new scripting runtime understands.

we have a project running unity 5.6.4 and scripting runtime 3.5

upgraded the engine to unity 2018.4.2f1 and scripting runtime 4.x

players data serialized in a file are not getting deserialized getting following exception

InvalidCastException: Object must implement IConvertible.
System.Convert.ChangeType (System.Object value, System.Type conversionType, System.IFormatProvider provider) (at :0)
System.Runtime.Serialization.FormatterConverter.Convert (System.Object value, System.Type type) (at :0)
System.Runtime.Serialization.SerializationInfo.GetValue (System.String name, System.Type type) (at :0)
System.Collections.Generic.Dictionary`2[TKey,TValue].OnDeserialization (System.Object sender) (at :0)
System.Runtime.Serialization.ObjectManager.RaiseDeserializationEvent () (at :0)
System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize (System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Runtime.Serialization.Formatters.Binary.__BinaryParser serParser, System.Boolean fCheck, System.Boolean isCrossAppDomain, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) (at :0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck, System.Boolean isCrossAppDomain, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) (at :0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck, System.Runtime.Remoting.Messaging.IMethodCallMessage methodCallMessage) (at :0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler, System.Boolean fCheck) (at :0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream, System.Runtime.Remoting.Messaging.HeaderHandler handler) (at :0)
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (System.IO.Stream serializationStream) (at :0)
Util.ReadFromBinaryFile[T] (System.String fileName) (at Assets/FactoryGame/Scripts/Util/Util.cs:721)
DemandGenerationDetails.loadData () (at Assets/FactoryGame/Animaition/Supermall/MapCustomers/DemandGenerationDetails.cs:2193)
DemandGenerationDetails.getInstance () (at Assets/FactoryGame/Animaition/Supermall/MapCustomers/DemandGenerationDetails.cs:2255)

Unfortunately, the .NET 3.5 and .NET 4.x scripting runtimes are incompatible when it comes to the BinaryFormatter. The layout of the serialized data changed significantly, so you cannot serialize with one version and deserialize with another.

Please suggest a solution because our application is live with unity version 5.6.4f1 but as because of Google’s new policies we need to upgrade project to unity 2018 and above to support 64 bit architectures

Unity 2018.4 supports both ARM64 on Android and the .NET 3.5 scripting runtime. I’d recommend using that configuration. Then it should be possible to change the serialization scheme for this data to something that has a format which can be used by both the old and the new scripting runtime.

You could also recreate the file you want to deserialize using the new scripting runtime.

Hello , we have recently updated to Unity 2020.3.21f1 , and migrated our games from Unity 5.6 . We have now noticed that , the serialized save data files can not be read by the updated version of our app. It seems like the problem is becasue of the depreciation of .Net 3.5 scripting runtime. Other than this problem everything looks fine and we don’t want to downgrade our Unity version as we know it would cause more problems as we have version on stores with Android Api Level 31 but , old version of unity not supports that api and google not alllows downgrading an api level on higher version numbers. Newly installed games works without problem already , but it is important that we make older version of save files to work on already installed devices. Do you have any suggestion how we can migrate those without deleting all the user data?

You will need to deserialize the data using the older version of Unity, then serialize it again using something that can be read by the newer version of Unity. I’m not quite sure how to do that in your situation specifically, but that is the general guideline.