Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Deserializing strings into objects with Json.NET

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading