I’m working on a library to parse Minecraft JSON files. However, they have a slightly weird format that I can’t figure out how to parse with Newtonsoft’s JSON.net:
{
"values": [
"some_object",
"another_object",
{
"name": "third_object",
"required": false
}
]
}
The class I’m trying to deserialize the values
array into looks like this:
class TagValue
{
public string Name;
public bool Required = false;
}
So for values which are just a string, it should set Name
to the string and leave Required
as false.
Is there a way I can do this? I’m very new to the library and can’t figure out how to do anything more advanced than the most basic deserialization.
>Solution :
Try this
[JsonConverter(typeof(TagValueConverter))]
class TagValue
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("required")]
public bool Required { get; set; }
private class TagValueConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string) ||
objectType == typeof(TagValue);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.String)
return new TagValue
{
Name = reader.Value as string
};
else
{
var jobj = JObject.Load(reader);
var obj = new TagValue();
serializer.Populate(jobj.CreateReader(), obj);
return obj;
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}
Then presumably you have/need a class for the outer object:
class TagValues
{
[JsonProperty("values")]
public TagValue[] Values { get; set; }
public static void TestMe()
{
string json = @"{
""values"": [
""some_object"",
""another_object"",
{
""name"": ""third_object"",
""required"": true
}
]
}";
var tags = JsonConvert.DeserializeObject<TagValues>(json);
Debug.Assert(tags.Values?.Length == 3);
Debug.Assert(tags.Values[0].Name == "some_object");
Debug.Assert(tags.Values[1].Name == "another_object");
Debug.Assert(tags.Values[2].Name == "third_object" &&
tags.Values[2].Required == true);
}
}
PS – You also should make those fields properties as was suggested in the comments.