How to deserialize json to a Dictionary<string,object> in a class using NetwornSoft.JsonConvert.DeserializeObject<T> in C#

Viewed 113

I'm having a problem with the deserialization of json to a class with a Dictionary<string,object> using Newtonsoft's JsonConvert.DeserializeObject() function.

Currently what's happening is it's just deserializing a string to the object value, where the string is the json for the class that was serialized.

The dictionary property in the class that's being serialized to JSON:

[Serializable]
public abstract class EntitySaveData
{
    [Header("Settings")]
    [SerializeField, Tooltip("A unique server-side identifier to bind EntitySaveData with EntityGameData and Entity components")]
    [JsonProperty("id")]
    protected string id = string.Empty;
    [JsonProperty("lvl")]
    public int Level { get; protected set; }
    [JsonProperty("hp")]
    public int CurrentHitPoints { get; protected set; }

    [JsonIgnore]
    public string Id => id;

    [JsonProperty("bsd")]
    public Dictionary<string, object> behaviourSaveDataByName = new Dictionary<string, object>(); 
}

The class for the object that's being added to the dictionary

[JsonObject(MemberSerialization.OptIn), Serializable]
public class SaveDataGeneratorBehaviour
{
    [JsonRequired, JsonProperty("cap")]
    private SaveDataCapacity saveDataCapacity;

    public SaveDataCapacity SaveDataCapacity => saveDataCapacity;

    [JsonConstructor]
    public SaveDataGeneratorBehaviour(float currentAmountStored)
    {
        saveDataCapacity = new SaveDataCapacity(currentAmountStored);
    }

    public void UpdateAmountStored(float currentAmountStored)
    {
        saveDataCapacity.UpdateAmountStored(currentAmountStored);
    }
}

The class nested in the class that's being saved. (Another employee did this, I don't know why).

public class SaveDataCapacity : SaveDataBehaviour
{
    [JsonRequired, JsonProperty("s")]
    private int currentAmountStored;
    [JsonRequired, JsonProperty("t")]
    private DateTime timeSaved;

    public int CurrentAmountStored => currentAmountStored;
    public DateTime TimeSaved => timeSaved;

    [JsonConstructor]
    public SaveDataCapacity(float currentAmountStored)
    {
        this.currentAmountStored = Mathf.RoundToInt(currentAmountStored);
        timeSaved = DateTime.Now;  // TODO: (Seb) Replace with server time
    }

    public void UpdateAmountStored(float currentAmountStored)
    {
        this.currentAmountStored = Mathf.RoundToInt(currentAmountStored);
        timeSaved = DateTime.Now;  // TODO: (Seb) Replace with server time
    }
}

The method used to deserialize the object

private static T TryDeserialize<T>(object obj, T deserializedObject)
{
    try
    {
        deserializedObject = JsonConvert.DeserializeObject<T>(obj.ToString());
    }
    catch (Exception e)
    {
        ChaosTheoryGames.Core.Logger.LogWarning(e.Message);
    }

    return deserializedObject;
}

The full JSON of the object where the EntitySaveData is nested in (In some kind of compressed format):

{\"buildings\":[{\"grid\":{\"x\":8,\"y\":9},\"state\":{\"s\":\"StateBuildingIslandIdle\",\"t\":0.0,\"end\":\"2022-01-05T21:31:33.978876+11:00\"},\"id\":\"Engine\",\"lvl\":1,\"hp\":500},{\"grid\":{\"x\":11,\"y\":10},\"state\":{\"s\":\"StateBuildingIslandBuilding\",\"t\":7.99000072,\"end\":\"2022-01-05T21:31:51.4714003+11:00\"},\"id\":\"Solar Panel\",\"lvl\":1,\"hp\":400,\"Gen_SD\":{\"cap\":{\"s\":0,\"t\":\"2022-01-05T21:31:42.4754811+11:00\"}}}]}

I've tried so many different attributes and such and I can't get it to work. I've read about using JsonConverters but I feel like it shouldn't be necessary for this problem.

Any advice would be greatly appreciated!

0 Answers
Related