Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json.NET: serializing/deserializing arrays

Tags:

json

arrays

.net

I'm using a Json.NET library. What's the most convenient way of serializing/deserializing arrays in JSON via C#? For example, I'm trying to deserialize the following text (reading from file):

{
    "Name": "Christina",
    "Gender": "female",
    "Favorite_numbers": [11, 25 ,23]
}

I'm reading the text above from file to a variable:

JObject o = JObject.Parse(File.ReadAllText("input.txt"))

And then, when I'm trying to extract an array [11, 24, 23] with the

int[] num = (int[]) o["Favorite_numbers"]

I receive an error.

What am I doing wrong? How do I correctly read an array? How do I correctly read a 2-dim arrays of the following kind [[1, 2, 3], [4, 5, 6]]?

like image 358
user217905 Avatar asked Nov 25 '09 19:11

user217905


2 Answers

The Favorite_numbers property is going to be of type JArray since there is no way for it to infer what type it should be. The most convenient way of deserializing that object is going to be to define a C# class for it and use the JsonConvert.DeserializeObject<T>(...) method(s) to deserialize the JSON to your defined class.

like image 125
Michael Morton Avatar answered Nov 07 '22 11:11

Michael Morton


Depends on what you're doing. In your case the easiest way would be to create a JsonConverter. So you could do the following:

public class IntArrayConverter : JsonCreationConverter<int[]>
{

    protected override int[] Create(Type objectType, JArray jArray)
    {
        List<int> tags = new List<int>();

        foreach (var id in jArray)
        {
            tags.Add(id.Value<int>());
        }

        return tags.ToArray();
    }
}

public abstract class JsonCreationConverter<T> : JsonConverter
{
    /// <summary>
    /// Create an instance of objectType, based properties in the JSON Array
    /// </summary>
    /// <param name="objectType">type of object expected</param>
    /// <param name="jObject">contents of JSON Array that will be deserialized</param>
    /// <returns></returns>
    protected abstract T Create(Type objectType, JArray jObject);

    public override bool CanConvert(Type objectType)
    {
        return typeof(T).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JArray jArray = JArray.Load(reader);

        T target = Create(objectType, jArray);

        return target;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

Then define your model with your new attribute:

public class Person
{  
    public string Name { get; set; }
    public string Gender { get; set; }
    [JsonConverter(typeof(IntArrayConverter))]
    public int[] Favorite_numbers { get; set; }
}

And you can use it as you normally would:

Person result = JsonConvert.DeserializeObject<Person>(@"{
                ""Name"": ""Christina"",
                ""Gender"": ""female"",
                ""Favorite_numbers"": [11, 25 ,23]
            }");
like image 45
Richie Avatar answered Nov 07 '22 12:11

Richie