SaladLab / Json.Net.Unity3D

Forked Newtonsoft.Json to support Unity3D
MIT License
918 stars 169 forks source link

Deserialize struct (Editor & iOS) #15

Closed t0chas closed 7 years ago

t0chas commented 7 years ago

On .Net and the standard Newtonsoft JSON nuget structs can be parsed implementing the Parse method.

https://gist.github.com/t0chas/af5bc562d3fe411af4e2f1aced153301

I am getting an ArgumentException

ArgumentException: Could not cast or convert from System.String to SmallFactories.Model.ProductItems. Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable (System.Object value, System.Type initialType, System.Type targetType) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Utilities/ConvertUtils.cs:668) Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast (System.Object initialValue, System.Globalization.CultureInfo culture, System.Type targetType) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Utilities/ConvertUtils.cs:639) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType (Newtonsoft.Json.JsonReader reader, System.Object value, System.Globalization.CultureInfo culture, Newtonsoft.Json.Serialization.JsonContract contract, System.Type targetType) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:1000) Rethrow as JsonSerializationException: Error converting value "SmallCirclex4" to type 'SmallFactories.Model.ProductItems'. Path 'Recipes[0].Inputs[0]', line 1, position 408. Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType (Newtonsoft.Json.JsonReader reader, System.Object value, System.Globalization.CultureInfo culture, Newtonsoft.Json.Serialization.JsonContract contract, System.Type targetType) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:1004) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:317) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList (IList list, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonArrayContract contract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, System.String id) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:1644) UnityEngine.Debug:LogException(Exception) HttpRestClient:thread_worker(Object) (at Assets/RestClient/HttpRestClient.cs:173)

Any thoughts? Thanks

t0chas commented 7 years ago

Hi! Sorry the Parse method is handled by ServiceStack magically.

In any case someone finds in need to parse a struct with Newtonsoft. you can follow my example at https://gist.github.com/t0chas/af5bc562d3fe411af4e2f1aced153301

iDreamsOfGame commented 4 years ago

Actually, you can let the struct implement System.Runtim.Serialization.ISerializable like this: [Serializable] public struct SecretInt32 : IComparable<SecretInt32>, ISerializable Json.net will serialize/deserialize the struct by using ISerializable constructor like the log below: 2020-02-22T17:48:01.676 Info Started deserializing Joyient.Childhood.Models.VO.SaveData. Path 'currentLevel', line 2, position 17. 2020-02-22T17:48:01.684 Info Deserializing ReSharp.Security.DataProtection.SecretInt64 using ISerializable constructor. Path 'currentLevel.v', line 3, position 8. 2020-02-22T17:48:01.690 Info Started deserializing ReSharp.Security.DataProtection.SecretInt64. Path 'currentLevel', line 4, position 3. 2020-02-22T17:48:01.690 Info Finished deserializing ReSharp.Security.DataProtection.SecretInt64. Path 'currentLevel', line 4, position 3. 2020-02-22T17:48:01.692 Info Deserializing ReSharp.Security.DataProtection.SecretInt32 using ISerializable constructor. Path 'energy.v', line 6, position 8. 2020-02-22T17:48:01.693 Info Started deserializing ReSharp.Security.DataProtection.SecretInt32. Path 'energy', line 7, position 3. 2020-02-22T17:48:01.693 Info Finished deserializing ReSharp.Security.DataProtection.SecretInt32. Path 'energy', line 7, position 3. 2020-02-22T17:48:01.693 Info Deserializing ReSharp.Security.DataProtection.SecretInt32 using ISerializable constructor. Path 'gold.v', line 9, position 8. 2020-02-22T17:48:01.694 Info Started deserializing ReSharp.Security.DataProtection.SecretInt32. Path 'gold', line 10, position 3. 2020-02-22T17:48:01.694 Info Finished deserializing ReSharp.Security.DataProtection.SecretInt32. Path 'gold', line 10, position 3. 2020-02-22T17:48:01.694 Info Deserializing ReSharp.Security.DataProtection.SecretInt64 using ISerializable constructor. Path 'startEnergyRestoreTimestamp.v', line 12, position 8. 2020-02-22T17:48:01.694 Info Started deserializing ReSharp.Security.DataProtection.SecretInt64. Path 'startEnergyRestoreTimestamp', line 13, position 3. 2020-02-22T17:48:01.694 Info Finished deserializing ReSharp.Security.DataProtection.SecretInt64. Path 'startEnergyRestoreTimestamp', line 13, position 3. 2020-02-22T17:48:01.695 Info Finished deserializing Joyient.Childhood.Models.VO.SaveData. Path '', line 14, position 1. 2020-02-22T17:48:01.695 Verbose Deserialized JSON: { "currentLevel": { "v": 0 }, "energy": { "v": 3 }, "gold": { "v": 100 }, "startEnergyRestoreTimestamp": { "v": 0 } } I think this is the best way to serialize/deserialize a struct in C# with Json.net