Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

JSON .NET for Unity

Discussion in 'Assets and Asset Store' started by Dustin-Horne, Sep 13, 2013.

  1. citizen_12

    citizen_12

    Joined:
    Jun 21, 2013
    Posts:
    33
    What version of JSON .NET is required to support WebGL deployment on Unity 5 (avoiding the infamous System.Reflection.Emit error)? Thx
     
  2. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    It's a beta build. You'll need to email me or pm me your invoice number and email address and I can send you the webgl beta build.
     
  3. MrEsquire

    MrEsquire

    Joined:
    Nov 5, 2013
    Posts:
    2,712
    Hi Sir,

    I was wondering if you can help me, I just opened latest JSON.Net but on import got the following errors, please see the screenshot attached, existing iOS project using 4.6.2p1 of Unity.
    Maybe you fixed these in a beta release, please can you provide me some feedback as I'm stuck at the moment going further in my project.

    Thank you
     

    Attached Files:

  4. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Looks like you or another asset has created MathUtils and StringUtils classes in the global namespace potentially... So it doesn't know which one to use.
     
  5. MrEsquire

    MrEsquire

    Joined:
    Nov 5, 2013
    Posts:
    2,712
    I see, sorry but do you know a workaround? Should I firstly import Json, then the other plugins..Im following a tutorial from the net (leaderboard creation with Azure) and did not go into great detail about debugging issues.. Maybe create a seperate folder??
     
  6. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Folders don't have anything to do with it. You'll need to find the mathutils and stringutils classes that aren't in a namespace and put them in a namespace. Then you'll have to update all the code that uses them.
     
  7. mr_zog

    mr_zog

    Joined:
    Jan 21, 2014
    Posts:
    165
    Hi!

    Does anybody have any experience with how this plugin works with iOS 64bit aka IL2CPP?
    We are having quite some trouble with porting our game and at some points get exceptions which look like they come from this plugin.
    Unfortunately I can't post the actual exception right now as I'm not on the mac anymore.

    Would be interesting if somebody experienced the same!
    Sometimes it read like it's because of something with "UnityEngine.Events.UnityAction.EndInvoke" which could be related to http://blogs.unity3d.com/2015/01/29/unity-4-6-2-ios-64-bit-support/


    Thanks!
     
  8. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    I haven't tried anything with the new event system, but your mileage will vary depending on how complex your serialization and deserialization is. Unity is continually fixing bugs and missing features with IL2CPP but there are still some that are showstoppers in some cases. Currently many of my customers are having trouble with Arrays and Multidimensional Arrays, but there should be an IL2CPP fix for that coming soon (Unity is aware of it and I think it may be fixed). Also, some generic methods are not yet supported... MakeGenericType<T> is not currently supported in IL2CPP completely... so if you have generic classes (luckily this doesn't affect generic collections) or things that are based off of generic interfaces, the deserializer may fail to create them, unless you've created them elsewhere and/or potentially have a static variant of them somewhere so the compiler knows how to invoke the method.

    It's been a bumpy frustrating ride... IL2CPP to be honest isn't quite ready for showtime in my opinion, however the Apple 64-bit deadline pushed the requirement for it to be released even though it is not quite complete. However, Unity have been doing a great job of continually improving it.

    One thing you might try is to create an instance of your object and then use JsonConvert.PopulateObject() instead of DeserializeObject which might help you get around some of the creation issues.

    Other than that... any exceptions and stack traces you can send me would be great as I can troubleshoot and see if I can find a workaround. Just to be realistic, so far I have been unable to workaround most problems as they are driven by IL2CPP limitations, but it's always possible that some of the new features of Unity (such as the event system) have created bugs that I'm not yet aware of so I'd be more than happy to take a look.
     
  9. mr_zog

    mr_zog

    Joined:
    Jan 21, 2014
    Posts:
    165
    Thanks for the prompt reply!
    I tried the latest Unity (4.6.2p2) and it didn't change much: I think some of the JSON errors are gone, but now we are getting more il2cpp errors on other places (e.g. gokit related). Our current plan is to just leave iOS for now and check back in a few weeks.
     
  10. sevensails

    sevensails

    Joined:
    Aug 22, 2013
    Posts:
    483
    There is really wrong with simple arrays on iOS.... Tons of bugs with my savegame on iOS, then I changed from arrays to List<> and now the bugs seems to be gone!
     
  11. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Yeah my frustration level with il2cpp is growing. I've been getting bombarded with emails still. Lots of bugs. :/.
     
  12. Rom-

    Rom-

    Joined:
    Nov 26, 2008
    Posts:
    89
    What was the solution for this?

    I tried your suggestion:

    But this does not work. Any ideas?
     
  13. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    No, could you provide me with a repro project? Part of the problem is the value bit of your dictionary is of type object so it has to know what to deserialize too. You have to use the typenamehandling.all for both serialization and deserialization so it stores the type with the json, but I'd need to see the repro to figure out why it would be hanging.
     
  14. chirhotec

    chirhotec

    Joined:
    Mar 30, 2010
    Posts:
    47
    Is it possible to build with JsonDotNet for Windows Phone 8.1 using the Mono Compiler?

    When I set the Compilation Overrides to None, and try to build, I get the following errors

    Assets/JsonDotNet/Source/WinRT/RT_JsonWriter.cs(30,14): error CS0234: The type or namespace name `Numerics' does not exist in the namespace `System'. Are you missing an assembly reference?
    Assets/JsonDotNet/Source/WinRT/Linq/RT_JToken.cs(29,14): error CS0234: The type or namespace name `Dynamic' does not exist in the namespace `System'. Are you missing an assembly reference?
    Assets/JsonDotNet/Source/WinRT/Linq/RT_JToken.cs(32,14): error CS0234: The type or namespace name `Numerics' does not exist in the namespace `System'. Are you missing an assembly reference?

    (note that I am using the latest from the asset store, v1.4.0)
     
  15. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    No its not because of platform differences. It has to compile differently. However if you email me your invoice number I can give you precompiled Assemblies. You would just drop one in the /editor folder and one in the /plugins/wp8 folder (I think, have to double check that for 8.1 and universal) and then the compilation overrides wouldn't affect it.
     
  16. chirhotec

    chirhotec

    Joined:
    Mar 30, 2010
    Posts:
    47
    Sent you an email
     
  17. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Got it. I'll get them sent over.
     
  18. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    @Dustin Horne, if I have some json that looks like this:

    Code (CSharp):
    1. {
    2.     "receipt": {
    3.         "quantity": "1",
    4.         "product_id": "wbjs.iap.special.coindoubler"
    5.     },
    6.     "status": 0
    7. }
    I can do this:

    Code (CSharp):
    1.             var dic = JsonConvert.DeserializeObject<Dictionary<string,object>>(json);
    2.  
    Which allows me to get dic["receipt"] and dic["status"] as objects. The type of dic["receipt"] is Newtonsoft.Json.Linq.JObject but I'd like to have a Dictionary<string,string> so I can easily access the elements "quantity" and "product_id".

    Is there an easy way to do this?

    Thanks.
     
  19. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Sure:
    Code (csharp):
    1.  
    2. var receipt = dic["receipt"].ToObject<Dictionary<string, string>>();
    3.  
    That should do it I believe.
     
    andymads likes this.
  20. Miggy

    Miggy

    Joined:
    Feb 9, 2010
    Posts:
    76
    Thanks for the great plugin! I'm having some trouble though with deserializing null objects. I get this error when there is a null Vector3 in the deserialized file:

    JsonSerializationException: Cannot deserialize JSON object into type 'System.Single'.

    I'm using a custom converter for Vector3 that looks like this:

    Code (CSharp):
    1. public class Vector3_JsonConverter : JsonConverter
    2. {
    3.     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    4.     {
    5.         if (value == null) return;
    6.        
    7.         Vector3 v = (Vector3)value;
    8.        
    9.         if (v == new Vector3())
    10.         {
    11.             writer.WriteNull();
    12.             return;
    13.         }
    14.        
    15.         writer.WriteStartObject();
    16.        
    17.         writer.WritePropertyName("x");
    18.         serializer.Serialize(writer, v.x);
    19.        
    20.         writer.WritePropertyName("y");
    21.         serializer.Serialize(writer, v.y);
    22.        
    23.         writer.WritePropertyName("z");
    24.         serializer.Serialize(writer, v.z);
    25.        
    26.         writer.WriteEndObject();
    27.     }
    28.    
    29.     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    30.     {
    31.         if (reader.TokenType == JsonToken.None) return null;
    32.        
    33.         reader.Read(); // Property X      
    34.         reader.Read(); // Value X
    35.         var x = (Single)serializer.Deserialize(reader, typeof(Single));
    36.        
    37.         reader.Read(); // Property Y
    38.         reader.Read(); // Value Y
    39.         var y = (Single)serializer.Deserialize(reader, typeof(Single));
    40.        
    41.         reader.Read(); // Property Z
    42.         reader.Read(); // Value Z
    43.         var z = (Single)serializer.Deserialize(reader, typeof(Single));
    44.        
    45.         reader.Read();
    46.        
    47.         return new Vector3(x, y, z);
    48.     }
    49.    
    50.     public override bool CanConvert(Type objectType)
    51.     {
    52.         return (objectType.Equals(typeof(Vector3)));
    53.     }
    54. }

    So I guess I'm not handling the null case properly. How would I do that?
     
  21. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    That would actually make sense because Vector3 is a value type and it's not nullable. First I would recommend doing the shorthand of Vector3.zero instead of new Vector3()... but, the real issue is that you're writing "null" and then trying to deserialize "null" into a Single. Single is also a non-nullable value type so it won't actually work. What you'll need to do is serialize your object as Vector3.zero and not "null". Now, if what you're really concerned about keeping your json compact by not writing out the Vector3 if it's zero, then you can write null but you'll have to modify your ReadJson property and if the value is "null" you'll have to return Vector3.zero and skip individually deserializing x, y and z.

    Edit:

    More specifically...
    Code (csharp):
    1.  
    2. if(reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.None)
    3.     return Vector3.zero;
    Edit 2:
    Looking at your code further, I think you might be also missing out on something... The first reader.Read() method actually would read past the start object character... then I think you'll want use reader.Value to get the value at the current location.
     
    Last edited: Feb 23, 2015
  22. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    I had to look because I couldn't remember the method... but your entire ReadJson method could be boiled down to this:

    Code (csharp):
    1.  
    2. public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    3.     {
    4.         if (reader.TokenType == JsonToken.None || reader.TokenType == JsonToken.Null)
    5.                  return Vector3.zero;
    6.  
    7.         return serializer.Deserialize(reader);
    8.    }
    9.  
    Basically this is saying... if the object you're trying to read is null, then return an empty default vector3. Otherwise, go ahead and deserialize the object normally. This will work fine even if you don't have all of the properties serialized. The call to Deserialize will create a new Vector3 and will populate it's x, y and z properties from your Json. Easy-peasey.
     
  23. Miggy

    Miggy

    Joined:
    Feb 9, 2010
    Posts:
    76
    Thanks for the rapid response. Adding the check for JsonToken.Null appears to have fixed the problem.

    I tried using the simplified ReadJson() method but it results in an InvalidCastException when deserializing a Vector3 List:


    InvalidCastException: Cannot cast from source type to destination type.
    System.Array.Copy (System.Array sourceArray, Int32 sourceIndex, System.Array destinationArray, Int32 destinationIndex, Int32 length) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Array.cs:997)
    Newtonsoft.Json.Utilities.CollectionUtils.ToArray (System.Array initial, System.Type type) (at Assets/JsonDotNet/Source/Utilities/CollectionUtils.cs:642)
    Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList (System.Type listType, System.Action`2 populateList) (at Assets/JsonDotNet/Source/Utilities/CollectionUtils.cs:613)
    Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateList (Newtonsoft.Json.JsonReader reader, System.String reference, Newtonsoft.Json.Serialization.JsonArrayContract contract) (at Assets/JsonDotNet/Source/Serialization/JsonSerializerInternalReader.cs:671)
     
  24. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Oh yeah sorry, my short example was assuming a single Vector3, not a collection. :)
     
  25. GFX47

    GFX47

    Joined:
    Dec 7, 2010
    Posts:
    124
    Hi Dustin,

    Is there a way to deserialize JSON data into an existing object?
    I want to avoid creating a new object and just overriding properties values in my existing object.

    Thanks.
     
  26. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Sure! Just use JsonConvert.PopulateObject(yourObject, jsonString);
     
  27. GFX47

    GFX47

    Joined:
    Dec 7, 2010
    Posts:
    124
    Missed that one, thanks!
     
    Dustin-Horne likes this.
  28. andymads

    andymads

    Joined:
    Jun 16, 2011
    Posts:
    1,614
    I missed that one too. Good to know.
     
  29. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    HI sir!
    Can i decode from PHP encode ??
     
  30. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
  31. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    can you give me example code how decode in unity from php? thx
     
  32. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Sure, can you show me what your JSON looks like coming back from the PHP server?
     
  33. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    [{"ItemName":"Weapon_02","ItemDescription":"simple bow","ItemType":"Weapon_02","ItemAgi":35,"ItemInt":23,"ItemStr":22},{"ItemName":"","ItemDescription":"","ItemType":"","ItemAgi":0,"ItemInt":0,"ItemStr":0},{"ItemName":"","ItemDescription":"","ItemType":"","ItemAgi":0,"ItemInt":0,"ItemStr":0},{"ItemName":"","ItemDescription":"","ItemType":"","ItemAgi":0,"ItemInt":0,"ItemStr":0},{"ItemName":"","ItemDescription":"","ItemType":"","ItemAgi":0,"ItemInt":0,"ItemStr":0}]
     
  34. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Code (csharp):
    1.  
    2. public class MyItem
    3. {
    4.      public string ItemName {get; set;}
    5.      public string ItemDescription {get; set;}
    6.      public string ItemType {get; set;}
    7.      public int ItemAgi {get; set;}
    8.      public int ItemInt {get; set;}
    9.      public int ItemStr {get; set;}
    10. }
    11.  
    Code (csharp):
    1.  
    2. var itemArray = JsonConvert.DeserializeObject<MyItem[]>(jsonFromWeb);
    3.  
    Or

    Code (csharp):
    1.  
    2. var itemList = JsonConvert.DeserializeObject<List<MyItem>>(jsonFromWeb);
    3.  
     
    Last edited: Mar 16, 2015
  35. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76


    jsonFromWeb its like public JSON jsonFromWeb = new JSON() or just www.text ???
     
    Last edited: Feb 28, 2015
  36. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    Assets/Photon Unity Networking/Editor/PhotonNetwork/AccountService.cs(181,45): error CS0433: The imported type `Newtonsoft.Json.JsonConvert' is defined multiple times

    Help PLZ
     
  37. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    It
    It will just be your www.text. The multiple definitions is because another asset has a newtonsoft.json DLL. In this case photon. Delete that DLL and you'll be fine.
     
  38. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    if i just delete this dll photon's work would be fine??
     
  39. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Yes because my asset is a drop in replacement. Photon will use my asset instead.
     
  40. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    ok i did it! thx, but i can't find your newtonsoft DLL why?? which now refers to photon?
     
  41. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Because my asset is a unity port of Newtonsoft. There is no DLL. It's full source code.
     
  42. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    nice but how often you update Newtonsoft json?
     
  43. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    When I need to. I'll be updating within a couple weeks with webgl updates and support and will be updating to a new major version of json .net (6.x) after unity 5 is released but that re-port will take a lot of time.
     
  44. Stephane-Imbert

    Stephane-Imbert

    Joined:
    Dec 30, 2014
    Posts:
    14
    FYI, we are seeing the issue with arrays not being de-serialized properly on iOS with il2cpp as well. Not a new issue looking at this thread but I can confirm that switching from arrays to List<> allowed us to work around the issue for now.
    Aside from that, switching to Json.Net has been a breeze so far, thanks for making and maintaining that package Dustin.
     
  45. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Yeah I'm going to follow up with support and see where they are on this one. There are a lot of people having the issue. Switching to List works but it's not convenient (or even possible) for everyone so they need to get it fixed. I also have a user having trouble with Enums and Guids but I think it has to do with the way he is deserializing (possibly using "object") so they are just being treated as strings.
     
  46. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    sorry Dustin, but i can't understand how to use this code! for example i need itemName so after (var itemArray = JsonConvert.DeserializeObject<MyItem[]>(jsonFromWeb);) i need to use the itemArray? like itemArray.itemName? can you explain me plz (((
     
  47. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    The json you posted is an array with multiple items. Also, ItemName is capitalized in your json. You would have to do something like:

    Code (csharp):
    1.  
    2. itemArray[0].ItemName;
    3.  
    Are you familiar with how to use an array in c#? If not I would highly recommend starting with some beginner tutorials and learn the language constructs. It would make this much easier.
     
  48. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    ok thx! so as i understand if i need for example 3 characters with name, lvl, type, i need 3 some blank like
    public class MyChar1
    {
    public string Name {get; set;}
    public string Level {get; set;}
    public string Type {get; set;}
    }
    public class MyChar2
    {
    public string Name {get; set;}
    public string Level {get; set;}
    public string Type {get; set;}
    }
    public class MyChar3
    {
    public string Name {get; set;}
    public string Level {get; set;}
    public string Type {get; set;}
    }
    and then var charArray1 = JsonConvert.DeserializeObject<MyChar1[]>(jsonFromWeb);
    var charArray2 = JsonConvert.DeserializeObject<MyChar2[]>(jsonFromWeb);
    var charArray3 = JsonConvert.DeserializeObject<MyChar3[]>(jsonFromWeb);
    use charArray1[0].Name = Name; charArray1[1].Level = Level; charArray1[2].Type = Type; and etc for other????
    sorry for scripting i don't know how paste script like you :((
    thx!
     
  49. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    No, you don't need 3 classes, they all have the same properties. Use the same class (just a MyChar class for example) and if you have 3 different sets of json coming from the web, just create 3 different array instances... so just like you did, but instead of MyChar1[] it's just MyChar[] for all 3.
     
  50. KeeLo

    KeeLo

    Joined:
    Nov 1, 2013
    Posts:
    76
    ok thanx very much ))) i'll try it