I am getting an ArgumentNullException when trying to deserialize JSON on device. Here is the exact error:
I get this when calling this code:private TMetadata ReadObject(string path) { var data = File.ReadAllText(path); var obj = JsonConvert.DeserializeObject(data, _settings); return (TMetadata) obj; }
I read through this thread and realized it was a linker problem. My project is set to Link All when building to device, and changing it to Don't Link is not feasible due to size constraints.
I inspected the json text and found the type that it was trying to deserialize, then went to that class and marked it as Preserve(AllMembers = true)]. I added the same attribute to any user defined class that was being used in the class. I still get the same error, however.
Does anyone have any tips? Is there at least any way I can get some more useful information from xamarin? When the exception happens it takes me to a seemingly random line - an event declaration in an unrelated class - and clicking on methods in the stack does nothing. I have no idea what the "method" parameter is.
Here's stack starting just after the ReadObject call:
Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull(object value, string parameterName) in
Newtonsoft.Json.Utilities.ExpressionReflectionDelegateFactory.CreateParametrizedConstructor(System.Reflection.MethodBase method) in
Newtonsoft.Json.Serialization.JsonArrayContract.CreateWrapper(System.Collections.Generic.Dictionary<Bluebeam.Studio.Client.SDK.Sessions.SessionMarkupId,Bluebeam.Studio.Client.SDK.Sessions.ServerState.Pending.PendingItems.PendingMarkupDto> list) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewList(Newtonsoft.Json.JsonTextReader reader, Newtonsoft.Json.Serialization.JsonArrayContract contract, bool createdFromNonDefaultCreator) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(Newtonsoft.Json.JsonTextReader reader, System.MonoType objectType, Newtonsoft.Json.Serialization.JsonArrayContract contract, Newtonsoft.Json.Serialization.JsonProperty member, object existingValue, string id) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(Newtonsoft.Json.JsonTextReader reader, System.MonoType objectType, Newtonsoft.Json.Serialization.JsonArrayContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonObjectContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonConverter propertyConverter, Newtonsoft.Json.Serialization.JsonObjectContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.JsonTextReader reader, Bluebeam.Studio.Client.SDK.Sessions.ServerState.Pending.PendingItems.PendingMarkupsData target) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Bluebeam.Studio.Client.SDK.Sessions.ServerState.Pending.PendingItems.PendingMarkupsData newObject, Newtonsoft.Json.JsonTextReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, string id) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(Newtonsoft.Json.JsonTextReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(Newtonsoft.Json.JsonTextReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(Newtonsoft.Json.JsonTextReader reader, System.Type objectType, bool checkAdditionalContent) in
Newtonsoft.Json.JsonSerializer.DeserializeInternal(Newtonsoft.Json.JsonTextReader reader, System.Type objectType) in
Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonTextReader reader, System.Type objectType) in
Newtonsoft.Json.JsonConvert.DeserializeObject(string value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) in
Newtonsoft.Json.JsonConvert.DeserializeObject(string value, Newtonsoft.Json.JsonSerializerSettings settings) in
The solution was to add --linkskip=Newtonsoft.Json to the additional mtouch args
Answers
I also added the --linkskip=AssemblyName to the additional mtouch arguments and had no luck.
The solution was to add --linkskip=Newtonsoft.Json to the additional mtouch args
You need to put the [Preserve(AllMembers = true)] attribute on any classes that are dynamically generated. This will prevent them from being stripped out.
https://stackoverflow.com/a/37123169/75947
Oh yes, I checked my code and found that I also added
[Preserve(AllMembers = true)]
to the class which callsJsonConvert.DeserializeObject
.