I'm having an issue deserializing a JSON string into a RootObject
class with 1 string property and a list of custom objects.
When I debug the application and the code deserializes the json I get my 'ErrorCode' property, "test", is populated in the RootObject
class but the 'meets' property is always null
.
The code sits in a cross platform Xamarin forms application currently, but I've pulled the code and class definitions out and ran them in a simple console application that worked first time with no issues. I'm struggling to figure out what I'm doing wrong.
My simple JSON object is the following:
{"meets": [
{
"VenueName": "O2"
},
{
"VenueName": "wembly"
},
{
"VenueName": "NEC"
}
],
"ErrorCode": "test"}
My class definitions:
[JsonObject(Id = "Meets")]
public class Meets
{
[JsonProperty(PropertyName = "VenueName")]
public string VenueName { get; set; }
}
public class RootObject
{
public List<Meets> Meets { get; set; }
public string ErrorCode { get; set; }
}
The code to hit the api and get the json object (which is blanked out and a smaller simple object in its place):
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading.Tasks;
using Xamarin.Forms;
using EliteNfcBet.Models;
using System.Net.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace EliteNfcBet.ViewModels
{
public class ItemsViewModel : BaseViewModel
{
public ObservableCollection<Meets> RaceMeets { get; set; }
public Command LoadItemsCommand { get; set; }
public ItemsViewModel ()
{
Title = "Select Meeting";
RaceMeets = new ObservableCollection<Meets>();
LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommand());
}
async Task ExecuteLoadItemsCommand()
{
if (IsBusy)
return;
IsBusy = true;
try
{
RaceMeets.Clear();
var result = await GetMeetingsAsync();
//RaceMeets = result;
//foreach (var meet in meets.Meets)
//{
// RaceMeets.Add(meet);
//}
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
public static async Task<RootObject> GetMeetingsAsync()
{
RootObject meet = new RootObject();
//List<Meet> meets = new List<Meet>();
HttpClient client = new HttpClient();
client.MaxResponseContentBufferSize = 256000;
var uri = new Uri(string.Format(Constants.RestUrl, string.Empty) + "/api/GetAvailablemeetings");
try
{
var response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
//var content = await response.Content.ReadAsStringAsync();
var content = "{\"meets\":[{\"VenueName\":\"O2\"},{\"VenueName\":\"wembly\"},{\"VenueName\":\"NEC\"}],\"ErrorCode\":\"test\"}";
if (!string.IsNullOrEmpty(content))
{
ITraceWriter traceWriter = new MemoryTraceWriter();
var settings = new JsonSerializerSettings
{
Error = (sender, args) =>
{
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}
},
TraceWriter = traceWriter
};
//result = JsonConvert.DeserializeObject<T>(json, settings);
meet = JsonConvert.DeserializeObject<RootObject>(content, settings);
Console.WriteLine(traceWriter);
}
//if (meets.Count > 0)
//{
// meet.MeetList = meets;
//}
}
}
catch (Exception ex)
{
meet.ErrorCode = "INTERNAL_ERROR";
}
return meet;
}
}
}
EDIT:
I've made some minor changes suggested which are below.
My Json string is now this:
"{\"Meets\":[{\"VenueName\":\"O2\"},{\"VenueName\":\"wembly\"},{\"VenueName\":\"NEC\"}],\"ErrorCode\":\"test\"}"
My classes are below. One thing to note is they are defined within a 'models' namespace in a seperate code file that is doing the deserializing.
namespace EliteNfcBet.Models
{
public class Meets
{
public string VenueName { get; set; }
}
public class RootObject
{
public List<Meets> Meets { get; set; }
public string ErrorCode { get; set; }
}
}
Again i have debugging output when deserializing which looks like it points to the fact that the Meets class member not being found?
{2018-05-28T23:12:22.987 Info Started deserializing EliteNfcBet.Models.RootObject. Path 'Meets', line 1, position 9.
2018-05-28T23:12:22.993 Info Started deserializing System.Collections.Generic.List`1[[NInterpret.InterpretedObject, NInterpret.Xamarin.Droid, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. Path 'Meets', line 1, position 10.
2018-05-28T23:12:22.994 Info Started deserializing EliteNfcBet.Models.RootObject. Path 'Meets[0].VenueName', line 1, position 23.
2018-05-28T23:12:22.994 Verbose Could not find member 'VenueName' on EliteNfcBet.Models.RootObject. Path 'Meets[0].VenueName', line 1, position 23.
2018-05-28T23:12:22.994 Info Finished deserializing EliteNfcBet.Models.RootObject. Path 'Meets[0]', line 1, position 28.
2018-05-28T23:12:22.995 Info Started deserializing EliteNfcBet.Models.RootObject. Path 'Meets[1].VenueName', line 1, position 42.
2018-05-28T23:12:22.995 Verbose Could not find member 'VenueName' on EliteNfcBet.Models.RootObject. Path 'Meets[1].VenueName', line 1, position 42.
2018-05-28T23:12:22.996 Info Finished deserializing EliteNfcBet.Models.RootObject. Path 'Meets[1]', line 1, position 51.
2018-05-28T23:12:22.997 Info Started deserializing EliteNfcBet.Models.RootObject. Path 'Meets[2].VenueName', line 1, position 65.
2018-05-28T23:12:22.997 Verbose Could not find member 'VenueName' on EliteNfcBet.Models.RootObject. Path 'Meets[2].VenueName', line 1, position 65.
2018-05-28T23:12:22.997 Info Finished deserializing EliteNfcBet.Models.RootObject. Path 'Meets[2]', line 1, position 71.
2018-05-28T23:12:22.998 Info Finished deserializing System.Collections.Generic.List`1[[NInterpret.InterpretedObject, NInterpret.Xamarin.Droid, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. Path 'Meets', line 1, position 72.
2018-05-28T23:12:23.009 Info Finished deserializing EliteNfcBet.Models.RootObject. Path '', line 1, position 92.
2018-05-28T23:12:23.009 Verbose Deserialized JSON:
{
"Meets": [
{
"VenueName": "O2"
},
{
"VenueName": "wembly"
},
{
"VenueName": "NEC"
}
],
"ErrorCode": "test"
}}
edit 3:
I've just came across this post which explains a lot! Seems like xamarin.forms has a known problem currently with reflection and so certain packages may not work correctly.
JsonConvert.SerializeObject always return {} in XamarinForms
Does anyone have any insight as to why this happens and when this will be resolved. Also a work around that I could implement so I can use debugging. Thanks.