Hopefully someone can help me with the following inconsistency occurring in a large JSON file that I am attempting to deserialize using Newtonsoft.Json.
One of the proper
the easiest way (not necessarily the cleanest) would be to manually alter the string before deserialising -
jsonString = jsonString.replace("\"roles\": {", "\"rolesContainer\": {");
jsonString = jsonString.replace("\"roles\":{", "\"rolesContainer\": {");
and then in your main code you would have both rolesContainer and roles as fields - and then merge them after
public List<Role> roles { get; set; }
public RoleContainer rolesContainer { get; set; }
public class RoleContainer {
Public List<Role> roles;
}
it's dirty, but it should work
You can handle this inconsistency with a JsonConverter
also. It will be a little different than the one you have, but the idea is very similar:
public class ArrayOrWrappedArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(List<T>).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Array)
{
return CreateListFromJArray((JArray)token, serializer);
}
if (token.Type == JTokenType.Object)
{
JObject wrapper = (JObject)token;
JProperty prop = wrapper.Properties().FirstOrDefault();
if (prop.Value.Type == JTokenType.Array)
{
return CreateListFromJArray((JArray)prop.Value, serializer);
}
}
// If the JSON is not what we expect, just return an empty list.
// (Could return null or throw an exception here instead if desired.)
return new List<T>();
}
private List<T> CreateListFromJArray(JArray array, JsonSerializer serializer)
{
List<T> list = new List<T>();
serializer.Populate(array.CreateReader(), list);
return list;
}
public override bool CanWrite => false;
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Then just add the converter to your Roles
property and you should be good to go:
[JsonProperty("roles")]
[JsonConverter(typeof(ArrayOrWrappedArrayConverter<Role>))]
public List<Role> Roles { get; set; }
Working demo: https://dotnetfiddle.net/F6qgQB