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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Exceptions while using Newtonsoft.Json in UWP Build

Discussion in 'Windows' started by cor2879, Jun 15, 2020.

  1. cor2879

    cor2879

    Joined:
    Sep 9, 2019
    Posts:
    10
    I'm using NewtonSoft.Json to serialize some objects to Json for storing off in PlayerPrefs. It works flawlessly in Unity for Windows but in UWP I'm seeing some odd exceptions deep in the Serializer call stack. I'm almost certain it's a bug in NewtonSoft.Json but maybe someone else has run into this and knows what I can do to work around it (outside of implementing my own Json serialization which I may have to do):

    Here is the class I'm trying to serialize:


    Code (CSharp):
    1. /**************************************************
    2. *  Difficulty.cs
    3. *
    4. *  copyright (c) 2019 Vyl Games
    5. **************************************************/
    6.  
    7. namespace VylGames.HuntTheMuglump.Scripts.Components
    8. {
    9.     using System;
    10.     using System.Collections.Generic;
    11.     using System.Linq;
    12.     using Newtonsoft.Json;
    13.     using UnityEngine;
    14.  
    15.     using VylGames.HuntTheMuglump.Scripts.Utilities;
    16.  
    17.     /// <summary>
    18.     /// Defines a range of values use for describing the possible difficulty settings.
    19.     /// </summary>
    20.     public enum DifficultySetting
    21.     {
    22.         /*
    23.         /// <summary>
    24.         /// The tutorial setting
    25.         /// </summary>
    26.         Tutorial = 0,
    27.         */
    28.        
    29.         /// <summary>
    30.         /// The beginner setting
    31.         /// </summary>
    32.         Beginner = 0,
    33.  
    34.         /// <summary>
    35.         /// The easy setting
    36.         /// </summary>
    37.         Easy,
    38.  
    39.         /// <summary>
    40.         /// The normal setting
    41.         /// </summary>
    42.         Normal,
    43.  
    44.         /// <summary>
    45.         /// The hard setting
    46.         /// </summary>
    47.         Hard,
    48.  
    49.         /// <summary>
    50.         /// The expert setting
    51.         /// </summary>
    52.         Expert,
    53.  
    54.         /// <summary>
    55.         /// The custom setting
    56.         /// </summary>
    57.         Custom
    58. #if DEBUG
    59.         /// <summary>
    60.         /// The black muglump insanity setting
    61.         /// </summary>
    62.         , BlackMuglumpInsanity
    63.  
    64.         /// <summary>
    65.         /// The black muglump test setting
    66.         /// </summary>
    67.         , BlackMuglumpTest
    68.  
    69.         /// <summary>
    70.         /// The blue muglump test
    71.         /// </summary>
    72.         , BlueMuglumpTest
    73.  
    74.         /// <summary>
    75.         /// The empty test
    76.         /// </summary>
    77.         , Empty
    78. #endif
    79.     };
    80.  
    81.     /// <summary>
    82.     /// Defines a structure for specifying the parameters used to build a dungeon
    83.     /// </summary>
    84.     public class Difficulty
    85.     {
    86.         public const string CustomModePlayerPrefsKey = "CustomMode";
    87.  
    88.         /// <summary>
    89.         /// The pre-defined difficulty settings.
    90.         /// </summary>
    91.         private static Dictionary<DifficultySetting, Difficulty> difficulties;
    92.  
    93.         private static Difficulty defaultDifficulty;
    94.  
    95.         private static Dictionary<DifficultySetting, Difficulty> Difficulties
    96.         {
    97.             get
    98.             {
    99.                 if (difficulties == null)
    100.                 {
    101.                     difficulties = GetDifficultiesInternal();
    102.                 }
    103.  
    104.                 return difficulties;
    105.             }
    106.         }
    107.  
    108.         public static Difficulty Default
    109.         {
    110.             get
    111.             {
    112.                 if (defaultDifficulty == null)
    113.                 {
    114.                     defaultDifficulty = Difficulties[DifficultySetting.Beginner];
    115.                 }
    116.  
    117.                 return defaultDifficulty;
    118.             }
    119.         }
    120.  
    121.         private static Dictionary<DifficultySetting, Difficulty> GetDifficultiesInternal()
    122.         {
    123.             var difficulties = new Dictionary<DifficultySetting, Difficulty>()
    124.             {
    125.                 {
    126.                     Components.DifficultySetting.Beginner,
    127.                     new Difficulty()
    128.                     {
    129.                         Setting = ConvertToInt32(Components.DifficultySetting.Beginner),
    130.                         MinimumRoomCount = 32,
    131.                         MuglumpCount = 1,
    132.                         BlackMuglumpCount = 0,
    133.                         BlueMuglumpCount = 0,
    134.                         BatCount = 1,
    135.                         PitCount = 1,
    136.                         ArrowCount = 3,
    137.                         FlashArrowCount = 1,
    138.                         NetArrowCount = 1
    139.                     }
    140.                 },
    141.                 {
    142.                     Components.DifficultySetting.Easy,
    143.                     new Difficulty()
    144.                     {
    145.                         Setting = ConvertToInt32(Components.DifficultySetting.Easy),
    146.                         MinimumRoomCount = 64,
    147.                         MuglumpCount = 3,
    148.                         BlackMuglumpCount = 0,
    149.                         BlueMuglumpCount = 0,
    150.                         BatCount = 3,
    151.                         PitCount = 3,
    152.                         ArrowCount = 5,
    153.                         FlashArrowCount = 2,
    154.                         NetArrowCount = 2
    155.                     }
    156.                 },
    157.                 {
    158.                     Components.DifficultySetting.Normal,
    159.                     new Difficulty()
    160.                     {
    161.                         Setting = ConvertToInt32(Components.DifficultySetting.Normal),
    162.                         MinimumRoomCount = 128,
    163.                         MuglumpCount = 5,
    164.                         BlackMuglumpCount = 1,
    165.                         BlueMuglumpCount = 0,
    166.                         BatCount = 6,
    167.                         PitCount = 6,
    168.                         ArrowCount = 10,
    169.                         FlashArrowCount = 3,
    170.                         NetArrowCount = 3
    171.                     }
    172.                 },
    173.                 {
    174.                     Components.DifficultySetting.Hard,
    175.                     new Difficulty()
    176.                     {
    177.                         Setting = ConvertToInt32(Components.DifficultySetting.Hard),
    178.                         MinimumRoomCount = 256,
    179.                         MuglumpCount = 12,
    180.                         BlackMuglumpCount = 3,
    181.                         BlueMuglumpCount = 1,
    182.                         BatCount = 12,
    183.                         PitCount = 12,
    184.                         ArrowCount = 18,
    185.                         FlashArrowCount = 4,
    186.                         NetArrowCount = 4,
    187.                         CoverScentCount = 1
    188.                     }
    189.                 },
    190.                 {
    191.                     Components.DifficultySetting.Expert,
    192.                     new Difficulty()
    193.                     {
    194.                         Setting = ConvertToInt32(Components.DifficultySetting.Expert),
    195.                         MinimumRoomCount = 256,
    196.                         MuglumpCount = 15,
    197.                         BlackMuglumpCount = 5,
    198.                         BlueMuglumpCount = 2,
    199.                         BatCount = 15,
    200.                         PitCount = 15,
    201.                         ArrowCount = 27,
    202.                         FlashArrowCount = 5,
    203.                         NetArrowCount = 5,
    204.                         CoverScentCount = 1
    205.                     }
    206.                 }
    207. #if DEBUG
    208.                 ,
    209.                 {
    210.                     Components.DifficultySetting.BlackMuglumpInsanity,
    211.                     new Difficulty()
    212.                     {
    213.                         Setting = ConvertToInt32(Components.DifficultySetting.BlackMuglumpInsanity),
    214.                         MinimumRoomCount = 256,
    215.                         MuglumpCount = 0,
    216.                         BlackMuglumpCount = 30,
    217.                         BatCount = 0,
    218.                         PitCount = 15,
    219.                         ArrowCount = 50,
    220.                         FlashArrowCount = 50,
    221.                         NetArrowCount = 50,
    222.                         CoverScentCount = 10
    223.                     }
    224.                 },
    225.                 {
    226.                     Components.DifficultySetting.BlackMuglumpTest,
    227.                     new Difficulty()
    228.                     {
    229.                         Setting = ConvertToInt32(Components.DifficultySetting.BlackMuglumpTest),
    230.                         MinimumRoomCount = 32,
    231.                         MuglumpCount = 0,
    232.                         BlackMuglumpCount = 1,
    233.                         BatCount = 0,
    234.                         PitCount = 0,
    235.                         ArrowCount = 4,
    236.                         FlashArrowCount = 4,
    237.                         NetArrowCount = 4
    238.                     }
    239.                 },
    240.                 {
    241.                     Components.DifficultySetting.BlueMuglumpTest,
    242.                     new Difficulty()
    243.                     {
    244.                         Setting = ConvertToInt32(Components.DifficultySetting.BlueMuglumpTest),
    245.                         MinimumRoomCount = 60,
    246.                         BlueMuglumpCount = 5,
    247.                         MuglumpCount = 0,
    248.                         BlackMuglumpCount = 0,
    249.                         PitCount = 0,
    250.                         BatCount = 0,
    251.                         ArrowCount = 10,
    252.                         FlashArrowCount = 10,
    253.                         NetArrowCount = 10,
    254.                         CoverScentCount = 10
    255.                     }
    256.                 },
    257.                 {
    258.                     Components.DifficultySetting.Empty,
    259.                     new Difficulty()
    260.                     {
    261.                         Setting = ConvertToInt32(Components.DifficultySetting.Empty),
    262.                         BlueMuglumpCount = 0,
    263.                         MuglumpCount = 0,
    264.                         BlackMuglumpCount = 0,
    265.                         PitCount = 0,
    266.                         BatCount = 0,
    267.                         MinimumRoomCount = 256,
    268.                         FlashArrowCount = 99,
    269.                         NetArrowCount = 99,
    270.                         CoverScentCount = 99
    271.                     }
    272.                 }
    273. #endif
    274.             };
    275.  
    276.             if (IsCustomModeEnabled())
    277.             {
    278.                 difficulties.Add(Components.DifficultySetting.Custom, GetCustomDifficulty());
    279.             }
    280.  
    281.             return difficulties;
    282.         }
    283.  
    284.         private DifficultySetting difficultySetting;
    285.  
    286.         /// <summary>
    287.         /// Prevents a default instance of the <see cref="Difficulty"/> class from being created.
    288.         /// </summary>
    289.         public Difficulty() { }
    290.  
    291.         /// <summary>
    292.         /// Gets the setting.
    293.         /// </summary>
    294.         /// <value>
    295.         /// The setting.
    296.         /// </value>
    297.         public int Setting
    298.         {
    299.             get => ConvertToInt32(this.difficultySetting);
    300.             set => this.difficultySetting = ConvertToDifficultySetting(value);
    301.         }
    302.  
    303.         /// <summary>
    304.         /// Gets the minimum room count.
    305.         /// </summary>
    306.         /// <value>
    307.         /// The minimum room count.
    308.         /// </value>
    309.         public int MinimumRoomCount { get; set; }
    310.  
    311.         /// <summary>
    312.         /// Gets the muglump count.
    313.         /// </summary>
    314.         /// <value>
    315.         /// The muglump count.
    316.         /// </value>
    317.         public int MuglumpCount { get; set; }
    318.  
    319.         /// <summary>
    320.         /// Gets the black muglump count.
    321.         /// </summary>
    322.         /// <value>
    323.         /// The black muglump count.
    324.         /// </value>
    325.         public int BlackMuglumpCount { get; set; }
    326.  
    327.         /// <summary>
    328.         /// Gets the blue muglump count.
    329.         /// </summary>
    330.         /// <value>
    331.         /// The blue muglump count.
    332.         /// </value>
    333.         public int BlueMuglumpCount { get; set; }
    334.  
    335.         /// <summary>
    336.         /// Gets the total muglump count.
    337.         /// </summary>
    338.         /// <value>
    339.         /// The total muglump count.
    340.         /// </value>
    341.         public int TotalMuglumpCount
    342.         {
    343.             get { return this.MuglumpCount + this.BlackMuglumpCount + this.BlueMuglumpCount; }
    344.         }
    345.  
    346.         /// <summary>
    347.         /// Gets or sets the bat count.
    348.         /// </summary>
    349.         /// <value>
    350.         /// The bat count.
    351.         /// </value>
    352.         public int BatCount { get; set; }
    353.  
    354.         /// <summary>
    355.         /// Gets or sets the pit count.
    356.         /// </summary>
    357.         /// <value>
    358.         /// The pit count.
    359.         /// </value>
    360.         public int PitCount { get; set; }
    361.  
    362.         /// <summary>
    363.         /// Gets or sets the arrow count.
    364.         /// </summary>
    365.         /// <value>
    366.         /// The arrow count.
    367.         /// </value>
    368.         public int ArrowCount { get; set; }
    369.  
    370.         /// <summary>
    371.         /// Gets or sets the flash arrow count.
    372.         /// </summary>
    373.         /// <value>
    374.         /// The flash arrow count.
    375.         /// </value>
    376.         public int FlashArrowCount { get; set; }
    377.  
    378.         /// <summary>
    379.         /// Gets or sets the net arrow count.
    380.         /// </summary>
    381.         /// <value>
    382.         /// The net arrow count.
    383.         /// </value>
    384.         public int NetArrowCount { get; set; }
    385.  
    386.         /// <summary>
    387.         /// Gets or sets the cover scent count.
    388.         /// </summary>
    389.         /// <value>
    390.         /// The cover scent count.
    391.         /// </value>
    392.         public int CoverScentCount { get; set; }
    393.  
    394.         /// <summary>
    395.         /// Gets the difficulty.
    396.         /// </summary>
    397.         /// <param name="setting">The setting.</param>
    398.         /// <returns></returns>
    399.         public static Difficulty GetDifficulty(DifficultySetting setting)
    400.         {
    401.             if (!Difficulties.ContainsKey(setting))
    402.             {
    403.                 return null;
    404.             }
    405.  
    406.             return Difficulties[setting];
    407.         }
    408.  
    409.         public static void SetCustomDifficulty(Difficulty customDifficulty)
    410.         {
    411.             if (!Difficulties.ContainsKey(Components.DifficultySetting.Custom) || !(customDifficulty.Setting == ConvertToInt32(Components.DifficultySetting.Custom)))
    412.             {
    413.                 return;
    414.             }
    415.  
    416.             Difficulties[Components.DifficultySetting.Custom] = customDifficulty;
    417.         }
    418.  
    419.         /// <summary>
    420.         /// Gets the difficulties.
    421.         /// </summary>
    422.         /// <returns></returns>
    423.         public static Difficulty[] GetDifficulties()
    424.         {
    425.             if (IsCustomModeEnabled())
    426.             {
    427.                 EnableCustomDifficulty();
    428.             }
    429.  
    430.             return Difficulties.Values.OrderBy(difficulty => difficulty.Setting).ToArray();
    431.         }
    432.  
    433.         public static bool IsCustomModeEnabled()
    434.         {
    435.             var dungeonCrawlerBadge = Badge.GetStaticBadges().Where(badge => badge.Name == "DungeonCrawler").FirstOrDefault();
    436.  
    437.             return dungeonCrawlerBadge != null && dungeonCrawlerBadge.Enabled;
    438.         }
    439.  
    440.         /// <summary>
    441.         /// Returns a <see cref="System.String" /> that represents this instance.
    442.         /// </summary>
    443.         /// <returns>
    444.         /// A <see cref="System.String" /> that represents this instance.
    445.         /// </returns>
    446.         public override string ToString()
    447.         {
    448.             return ConvertToDifficultySetting(this.Setting).ToString();
    449.         }
    450.  
    451.         private static Difficulty GetCustomDifficulty()
    452.         {
    453.             Difficulty customDifficulty = null;
    454.  
    455.             if (!PlayerPrefsManager.IsKeyRegistered(CustomModePlayerPrefsKey, PlayerPrefsDataType.Json))
    456.             {
    457.                 PlayerPrefsManager.RegisterKey(CustomModePlayerPrefsKey, PlayerPrefsDataType.Json);
    458.             }
    459.  
    460.             customDifficulty = PlayerPrefsManager.GetData<Difficulty>(CustomModePlayerPrefsKey);
    461.  
    462.             if (customDifficulty == null || customDifficulty.Setting != ConvertToInt32(Components.DifficultySetting.Custom))
    463.             {
    464.                 customDifficulty = new Difficulty() { Setting = ConvertToInt32(Components.DifficultySetting.Custom), MinimumRoomCount = 50 };
    465.             }
    466.  
    467.             return customDifficulty;
    468.         }
    469.  
    470.         public static void SaveCustomDifficulty()
    471.         {
    472.             if (!Difficulties.ContainsKey(Components.DifficultySetting.Custom))
    473.             {
    474.                 return;
    475.             }
    476.  
    477.             SaveCustomDifficultyUnsafe();
    478.         }
    479.  
    480.         private static void SaveCustomDifficultyUnsafe()
    481.         {
    482.             var customDifficulty = Difficulties[Components.DifficultySetting.Custom];
    483.  
    484.             PlayerPrefsManager.SetDataProperty(CustomModePlayerPrefsKey, customDifficulty);
    485.         }
    486.  
    487.         public static void EnableCustomDifficulty()
    488.         {
    489.             if (!Difficulties.ContainsKey(Components.DifficultySetting.Custom))
    490.             {
    491.                 Difficulties.Add(Components.DifficultySetting.Custom, GetCustomDifficulty());
    492.             }
    493.         }
    494.  
    495.         public static void DisableCustomDifficulty()
    496.         {
    497.             if (Difficulties.ContainsKey(Components.DifficultySetting.Custom))
    498.             {
    499.                 SaveCustomDifficultyUnsafe();
    500.                 Difficulties.Remove(Components.DifficultySetting.Custom);
    501.                 Settings.Difficulty = Difficulty.Default;
    502.             }
    503.         }
    504.  
    505.         public void SetDifficultySetting(DifficultySetting value)
    506.         {
    507.             this.Setting = ConvertToInt32(value);
    508.         }
    509.  
    510.         public DifficultySetting GetDifficultySetting()
    511.         {
    512.             return (DifficultySetting)this.Setting;
    513.         }
    514.  
    515.         public static DifficultySetting ConvertToDifficultySetting(int value)
    516.         {
    517.             return (DifficultySetting)value;
    518.         }
    519.  
    520.         public static int ConvertToInt32(DifficultySetting value)
    521.         {
    522.             return (int)value;
    523.         }
    524.     }
    525.  
    526. }
    527.  
    And here is the code that invokes the Json Serializer

    Code (CSharp):
    1.         public static void SetDataProperty<TData>(string keyName, TData data, JsonConverter jsonConverter)
    2.         {
    3.             if (!Keys.ContainsKey(keyName))
    4.             {
    5.                 throw new PlayerPrefsException($"The key {keyName} is not registered.");
    6.             }
    7.  
    8.             if (Keys[keyName] != PlayerPrefsDataType.Json)
    9.             {
    10.                 throw new PlayerPrefsException($"The key {keyName} is not registered as a JSON data type.");
    11.             }
    12.  
    13.             try
    14.             {
    15.                 if (jsonConverter != null)
    16.                 {
    17.                     var settings = new JsonSerializerSettings();
    18.                     settings.Converters.Add(jsonConverter);
    19.                     PlayerPrefs.SetString(keyName, JsonConvert.SerializeObject(data, settings));
    20.                 }
    21.                 else
    22.                 {
    23.                     PlayerPrefs.SetString(keyName, JsonConvert.SerializeObject(data));
    24.                 }
    25.             }
    26.             catch (Exception ex)
    27.             {
    28.                 Debug.Log($"Exception: (key: {keyName}, value: {(!object.Equals(data, default(TData)) ? data.ToString() : "(default)")})");
    29.                 Debug.Log(ex.ToString());
    30.  
    31.                 throw;
    32.             }
    33.  
    34.             PlayerPrefsManager.SavePlayerPrefs();
    35.         }
    And here is the call stack:

    Newtonsoft.Json.JsonSerializationException: Error getting value from 'Setting' on 'VylGames.HuntTheMuglump.Scripts.Components.Difficulty'. ---> System.NullReferenceException: Object reference not set to an instance of an object.
    at System.Linq.Expressions.Interpreter.LightLambda.MakeRunDelegateCtor (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
    at System.Linq.Expressions.Interpreter.LightLambda.GetRunDelegateCtor (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
    at System.Linq.Expressions.Interpreter.LightLambda.MakeDelegate (System.Type delegateType) [0x00000] in <00000000000000000000000000000000>:0
    at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate (System.Runtime.CompilerServices.IStrongBox[] closure) [0x00000] in <00000000000000000000000000000000>:0
    at System.Linq.Expressions.Interpreter.LightDelegateCreator.CreateDelegate () [0x00000] in <00000000000000000000000000000000>:0
    at System.Linq.Expressions.LambdaExpression.Compile (System.Boolean preferInterpretation) [0x00000] in <00000000000000000000000000000000>:0
    at System.Linq.Expressions.LambdaExpression.Compile () [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Utilities.ExpressionReflectionDelegateFactory.CreateGet[T] (System.Reflection.PropertyInfo propertyInfo) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Utilities.ReflectionDelegateFactory.CreateGet[T] (System.Reflection.MemberInfo memberInfo) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue (System.Object target) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContainerContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.Serialization.JsonContract& memberContract, System.Object& memberValue) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract collectionContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContract valueContract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonSerializer.SerializeInternal (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonSerializer.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonConvert.SerializeObjectInternal (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializer jsonSerializer) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value) [0x00000] in <00000000000000000000000000000000>:0
    at VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsManager.SetDataProperty[TData] (System.String keyName, TData data, Newtonsoft.Json.JsonConverter jsonConverter) [0x00000] in <00000000000000000000000000000000>:0
    at VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsObjectProperty1[TValue].Save () [0x00000] in <00000000000000000000000000000000>:0 at VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsProperty1[TValue].Set (TValue value) [0x00000] in <00000000000000000000000000000000>:0
    at VylGames.HuntTheMuglump.Scripts.Components.Settings.set_Difficulty (VylGames.HuntTheMuglump.Scripts.Components.Difficulty value) [0x00000] in <00000000000000000000000000000000>:0
    at VylGames.HuntTheMuglump.Scripts.UI.TitleScreenSettingsPanelBehaviour.Save () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Events.UnityAction.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Events.InvokableCall.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.UI.Button.Press () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.ExecuteEvents+EventFunction1[T1].Invoke (T1 handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <00000000000000000000000000000000>:0 at UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction1[T1] functor) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.ReleaseMouse (UnityEngine.EventSystems.PointerEventData pointerEvent, UnityEngine.GameObject currentOverGo) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.ProcessMousePress (UnityEngine.EventSystems.PointerInputModule+MouseButtonEventData data) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent (System.Int32 id) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.Process () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.EventSystem.Update () [0x00000] in <00000000000000000000000000000000>:0
    --- End of inner exception stack trace ---
    at Newtonsoft.Json.Serialization.ExpressionValueProvider.GetValue (System.Object target) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContainerContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.Serialization.JsonContract& memberContract, System.Object& memberValue) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract collectionContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue (Newtonsoft.Json.JsonWriter writer, System.Object value, Newtonsoft.Json.Serialization.JsonContract valueContract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonSerializer.SerializeInternal (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonSerializer.Serialize (Newtonsoft.Json.JsonWriter jsonWriter, System.Object value, System.Type objectType) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonConvert.SerializeObjectInternal (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializer jsonSerializer) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) [0x00000] in <00000000000000000000000000000000>:0
    at Newtonsoft.Json.JsonConvert.SerializeObject (System.Object value) [0x00000] in <00000000000000000000000000000000>:0
    at VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsManager.SetDataProperty[TData] (System.String keyName, TData data, Newtonsoft.Json.JsonConverter jsonConverter) [0x00000] in <00000000000000000000000000000000>:0
    at VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsObjectProperty1[TValue].Save () [0x00000] in <00000000000000000000000000000000>:0 at VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsProperty1[TValue].Set (TValue value) [0x00000] in <00000000000000000000000000000000>:0
    at VylGames.HuntTheMuglump.Scripts.Components.Settings.set_Difficulty (VylGames.HuntTheMuglump.Scripts.Components.Difficulty value) [0x00000] in <00000000000000000000000000000000>:0
    at VylGames.HuntTheMuglump.Scripts.UI.TitleScreenSettingsPanelBehaviour.Save () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Events.UnityAction.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Events.InvokableCall.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.UI.Button.Press () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.ExecuteEvents+EventFunction1[T1].Invoke (T1 handler, UnityEngine.EventSystems.BaseEventData eventData) [0x00000] in <00000000000000000000000000000000>:0 at UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction1[T1] functor) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.ReleaseMouse (UnityEngine.EventSystems.PointerEventData pointerEvent, UnityEngine.GameObject currentOverGo) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.ProcessMousePress (UnityEngine.EventSystems.PointerInputModule+MouseButtonEventData data) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent (System.Int32 id) [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.StandaloneInputModule.Process () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.EventSystems.EventSystem.Update () [0x00000] in <00000000000000000000000000000000>:0
    UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsManager:SetDataProperty(String, TData, JsonConverter)
    VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsObjectProperty1:Save() VylGames.HuntTheMuglump.Scripts.Components.PlayerPrefsProperty1:Set(TValue)
    VylGames.HuntTheMuglump.Scripts.Components.Settings:set_Difficulty(Difficulty)
    VylGames.HuntTheMuglump.Scripts.UI.TitleScreenSettingsPanelBehaviour:Save()
    UnityEngine.Events.UnityAction:Invoke()
    UnityEngine.Events.InvokableCall:Invoke()
    UnityEngine.Events.UnityEvent:Invoke()
    UnityEngine.UI.Button:press()
    UnityEngine.UI.Button:OnPointerClick(PointerEventData)
    UnityEngine.EventSystems.ExecuteEvents:Execute(IPointerClickHandler, BaseEventData)
    UnityEngine.EventSystems.EventFunction1:Invoke(T1, BaseEventData) UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction1)
    UnityEngine.EventSystems.StandaloneInputModule:ReleaseMouse(PointerEventData, GameObject)
    UnityEngine.EventSystems.StandaloneInputModule:processMousePress(MouseButtonEventData)
    UnityEngine.EventSystems.StandaloneInputModule:processMouseEvent(Int32)
    UnityEngine.EventSystems.StandaloneInputModule:processMouseEvent()
    UnityEngine.EventSystems.StandaloneInputModule:process()
    UnityEngine.EventSystems.EventSystem:Update()

    Using the log output I am able to determine with 100% certainty that the object I am passing in to JsonConvert.SerializeObject is definitely not null at the time of invocation. No there is a problem here that is much deeper and that probably has little to do with my code. I'm curious to see if anyone else has encountered a bug like this. Any help is appreciated. Thanks!
     
  2. cor2879

    cor2879

    Joined:
    Sep 9, 2019
    Posts:
    10
    Well I didn't get a response from here or on the Github forum for Newtonsoft ;-D so I implemented a workaround. While I would love to be able to use SerializeObject and DeserializeObject, it seems there is a bug when this is compiled into a UWP Native assembly. So instead I am serializing to Json 'manually' and deseriailzing using the Newtonsoft.Json.Linq JObject and JArray like this:

    Code (CSharp):
    1.         public string ToJson()
    2.         {
    3.             // Template: $"\"{nameof()}\":\"{}\"," +
    4.  
    5.             return $"{{\"{nameof(this.Setting)}\":\"{this.Setting}\"," +
    6.                 $"\"{nameof(this.MinimumRoomCount)}\":\"{this.MinimumRoomCount}\"," +
    7.                 $"\"{nameof(this.MuglumpCount)}\":\"{this.MuglumpCount}\"," +
    8.                 $"\"{nameof(this.BlackMuglumpCount)}\":\"{this.BlackMuglumpCount}\"," +
    9.                 $"\"{nameof(this.BlueMuglumpCount)}\":\"{this.BlueMuglumpCount}\"," +
    10.                 $"\"{nameof(this.BatCount)}\":\"{this.BatCount}\"," +
    11.                 $"\"{nameof(this.PitCount)}\":\"{this.PitCount}\"," +
    12.                 $"\"{nameof(this.ArrowCount)}\":\"{this.ArrowCount}\"," +
    13.                 $"\"{nameof(this.FlashArrowCount)}\":\"{this.FlashArrowCount}\"," +
    14.                 $"\"{nameof(this.NetArrowCount)}\":\"{this.NetArrowCount}\"," +
    15.                 $"\"{nameof(this.CoverScentCount)}\":\"{this.CoverScentCount}\"," +
    16.                 "}";
    17.         }
    18.  
    19.         public Difficulty FromJson(string json)
    20.         {
    21.             var jsonObject = JObject.Parse(json);
    22.  
    23.             // Template jsonObject[nameof()].ToString()
    24.  
    25.             this.Setting = (DifficultySetting)Enum.Parse(typeof(DifficultySetting), jsonObject[nameof(this.Setting)].ToString());
    26.             this.MinimumRoomCount = int.Parse(jsonObject[nameof(this.MinimumRoomCount)].ToString());
    27.             this.MuglumpCount = int.Parse(jsonObject[nameof(this.MuglumpCount)].ToString());
    28.             this.BlackMuglumpCount = int.Parse(jsonObject[nameof(this.BlackMuglumpCount)].ToString());
    29.             this.BlueMuglumpCount = int.Parse(jsonObject[nameof(this.BlueMuglumpCount)].ToString());
    30.             this.BatCount = int.Parse(jsonObject[nameof(this.BatCount)].ToString());
    31.             this.PitCount = int.Parse(jsonObject[nameof(this.PitCount)].ToString());
    32.             this.ArrowCount = int.Parse(jsonObject[nameof(this.ArrowCount)].ToString());
    33.             this.FlashArrowCount = int.Parse(jsonObject[nameof(this.FlashArrowCount)].ToString());
    34.             this.NetArrowCount = int.Parse(jsonObject[nameof(this.NetArrowCount)].ToString());
    35.             this.CoverScentCount = int.Parse(jsonObject[nameof(this.CoverScentCount)].ToString());
    36.  
    37.             return this;
    38.         }
    39.  
    40.         IJsonSerializable IJsonSerializable.FromJson(string json)
    41.         {
    42.             return this.FromJson(json);
    43.         }
    I tested this in UWP and it seems to work. Leaving this here in case anyone runs into a similar problem in the future.
     
    PannipaSra likes this.