Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.
string json = @"{
'symbol':'XX',
'column_names":["Date","Open","High","Low","Close","Volume"],
'data':[
['2014-01-02',25.78,25.82,25.47,25.79,31843697.0],
['2013-12-31',25.81,26.04,25.77,25.96,22809682.0]]}";

public class DailyData
{
    public string symbol { get; set; }
    public List<OneDay> data { get; set; }
}

public class OneDay
{
     public DateTime date { get; set; }
     public double open { get; set; }
     public double high { get; set; }
     public double low { get; set; }
     public double close { get; set; }
     public double volume { get; set; }
}

DailyData dd = JsonConvert.DeserializeObject<DailyData>(json);

This is my json string and class I'm trying to deserialize it into with Json.net. It will work if I change public List<OneDay> data { get; set; } to public List<object> data { get; set; }. But in this case I have to do more steps further. Is there a neat solution to deserialize it in one go?

share|improve this question

1 Answer 1

up vote 3 down vote accepted

Yes, you have to use the JsonConverter class to tell the deserializer how to map an array of values to the OneDay class.

Example:

void Main()
{
    string json = @"{
                        'symbol':'XX',
                        'column_names':['Date','Open','High','Low','Close','Volume'],
                        'data':[
                            ['2014-01-02',25.78,25.82,25.47,25.79,31843697.0],
                            ['2013-12-31',25.81,26.04,25.77,25.96,22809682.0]
                                ]
                    }";

    DailyData dd = JsonConvert.DeserializeObject<DailyData>(json);
    dd.Dump();
}

class OneDayJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        OneDay obj = new OneDay();
        obj.date = reader.ReadAsDateTime() ?? DateTime.MinValue;
        obj.open = (double)(reader.ReadAsDecimal() ?? 0);
        obj.high = (double)(reader.ReadAsDecimal()?? 0);
        obj.low = (double)(reader.ReadAsDecimal() ?? 0);
        obj.close = (double)(reader.ReadAsDecimal() ?? 0);
        obj.volume = (double)(reader.ReadAsDecimal() ?? 0);
        reader.Read(); 
        return obj;
    }

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

public class DailyData
{
    public string symbol { get; set; }
    public List<OneDay> data { get; set; }
}

[JsonConverter(typeof(OneDayJsonConverter))]
public class OneDay
{
    public DateTime date { get; set; }
    public double open { get; set; }
    public double high { get; set; }
    public double low { get; set; }
    public double close { get; set; }
    public double volume { get; set; }
}

Result:

enter image description here

share|improve this answer
    
Nice, thanks! dd.Dump() is apparently typo? –  Dork Jan 3 '14 at 18:43
1  
Dump() is an extension method provided by LINQPad which is used to provide the output you see in the screenshot above. You should give LINQPad a try. –  sloth Jan 4 '14 at 11:09
    
Thank Dominic, I will research it –  Dork Jan 4 '14 at 13:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.