Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by Rocketman_Dan · Jun 16, 2018 at 03:58 PM · serializationjsondictionarydeserialization

Deserializing dictionary with 'Json.Net' for Unity returns a null object.

I'm using the Json.Net pluggin for unity which adds support for Vectors and Matrices to standard Newtonsoft.Json but for what I'm doing only knowledge of default json.net (Newtonsoft.Json) should be relevant.

This json object contains a list of Person object which each have a dictionary on them.

 {
   "$type": "PeopleDataObject, Assembly-CSharp",
   "People": {
     "$type": "System.Collections.Generic.List`1[[Person, Assembly-CSharp]], 
                                                                  mscorlib",
     "$values": [
       {
         "$type": "Person, Assembly-CSharp",
         "Id": 0,
         "FirstName": "Daffy",
         "LastName": "Duck",
         "Age": 0,
         "Sex": true,
         "Stats": {
           "$type": "System.Collections.Generic.Dictionary`2[[System.String, 
                             mscorlib],[System.Int32, mscorlib]], mscorlib",
           "str": 9,
           "dex": 13,
           "con": 9,
           "int": 13,
           "wis": 10,
           "cha": 8
         }
       },
       {
         "$type": "Person, Assembly-CSharp",
         "Id": 1,
         "FirstName": "Wilma",
         "LastName": "Flintstone",
         "Age": 0,
         "Sex": false,
         "Stats": {
           "$type": "System.Collections.Generic.Dictionary`2[[System.String, 
             mscorlib],[System.Int32, mscorlib]], mscorlib",
           "str": 7,
           "dex": 9,
           "con": 9,
           "int": 12,
           "wis": 12,
           "cha": 12
         }
       }
     ]
   },
   "Count": 2
 }

I checked that the string read doesn't come out malformed by writing the it to another file so I know that everything serializes correctly but on deserialization the dictionaries are lost so that when I go to use it or save it again they're null. The debugger identifies it as a null object. The code below follows the documentation for general objects but I couldn't find a specific case for objects containing dictionaries. I made sure to include TypeNameHandling so as to try to make sure it knew to deserialize into a dictionary but I'm not getting that result.

 private void LoadRoster()
 {
     string path = Path.Combine(Application.streamingAssetsPath, "PeopleData.json");
     string debug = Path.Combine(Application.streamingAssetsPath, "debug.json");
     if (!File.Exists(path))
     {
         Debug.Log("NO SAVE FILE RECOGNISED");
     }
     else
     {
         PeopleDataObject allPeople = PeopleDataObject.Instance;
         string jsonString = File.ReadAllText(path);

         //check that the file is read correctly
         File.WriteAllText(debug, jsonString);

         allPeople = JsonConvert.DeserializeObject<PeopleDataObject>(jsonString, new JsonSerializerSettings
         {
             TypeNameHandling = TypeNameHandling.All
         });
         People = allPeople.People;
         Person.AllTimeCount = allPeople.Count;
         Debug.Log("Loaded");
     }
 }

It's trying to deserialize to the following PeopleDataObject class which itself contains a list of Person which I will also provide below.

PeopleDataObject:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class PeopleDataObject
 {
     //<Singleton Boilerplate>
     private static PeopleDataObject instance = null;
     private static readonly object padlock = new object();
 
     PeopleDataObject() {}
 
     public static PeopleDataObject Instance
     {
         get
         {
             lock(padlock)
             {
                 if (instance == null)
                 {
                     instance = new PeopleDataObject();
                 }
                 return instance;
             }
         }
     }
     //</Singletone Boilerplate>
 
     public List<Person> People { get; set; }
     public int Count { get; set; }
 }


Person:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class Person
 {
 
     public int Id { get; private set; }
     public string FirstName { get; set; }
     public string LastName { get; set; }
     public int Age { get; private set; }
     public bool Sex { get; private set; } //true = male, false = female
     public Dictionary<string, int> Stats { get; private set; }
 
     public static int AllTimeCount { get; set; }
 
     private GameObject messageController;
 
     public Person(string first, string last, bool sex, GameObject controller)
     {
         Debug.Log(" overload 1");
         FirstName = first;
         LastName = last;
         Age = 0;
         Sex = sex;
         Id = AllTimeCount;
         AllTimeCount++;
 
         if (controller != null)
             messageController = controller;
         else
             messageController = GameObject.Find("PersonManager");
 
         //if sex is true (male) colour modifier is blue, else colour modifier is pink
         string colourMod = sex ? "#4286f4" : "#ff56ff";
 
         Notification(string.Format("<{0}>{1} {2}</color> was born. ", colourMod, first, last));
 
     }
 
     public Person(int id, string first, string last, bool sex, Dictionary<string, int> stats)
     {
         Debug.Log("overload 2");
         Id = id;
         FirstName = first;
         LastName = last;
         Sex = sex;
         Stats = stats;
     }
 
     public Person()
     {
         Debug.Log("overload 3");
     }
 
     public void SetStats(Dictionary<string, int> s)
     {
         Stats = s;
     }
 
     public void IncrementAge()
     {
         Age++;
     }
 
     public void Notification(string message)
     {
         MessageController controller = messageController.GetComponent<MessageController>();
         controller.PostMessage(message);
     }
 }

By the way I am aware that messageController in Person is null when constructors 2 or 3 are used but that's not my concern right now and it has no bearing on the current issue but it will be seen to.

I've been stuck on this for some time. I already know I'm an idiot but I'd much appreciate a helping hand to tell me why I'm an idiot.

Cheers, Dan

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

89 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Serialize / Deserialize dictionary with unity serialization system, without using lists for keys and values 1 Answer

Json deserialisation of server results? 1 Answer

How can I save a Dictionary in a class to JSON? 2 Answers

how to deserialize json with arbitrary string keys using JsonUtility(unity c#)? 4 Answers

Serialization errors.. 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges