-1

I need to have a json with this format (when data is null, just retrieve the time field):

var chartData = [
            {
                "time": "0",
                "value": -0.307
            },
            {
                "time": "1",
                "value": -0.168
            },
            {
                "time": "2"
            },
            {
                "time": "3",
                "value": -0.027
            }
]

I have created two classes:

  • dataV1 (time)
  • dataV2 (time, value -> should be double)

Code:

public class dataV1
{
    public string time { get; set; }

    public dataV1(string Ptime)
    {
        this.time = Ptime;      
    }

    public dataV1() { }
}

public class dataV2
{
    public string time { get; set; }
    public double value { get; set; }

    public dataV2(string Ptime, double Pvalue)
    {
        this.time = Ptime;   
        this.value = Pvalue;   
    }

    public dataV2() { }
}

Then in the C# sql:

if (sqlReader["value"] != DBNull.Value) 

How can I combine both classes and use dataV1 when value is null and dataV2 when we have a not null value?

And retrieve a Json result

return Json(new
{
    chartData,
}, JsonRequestBehavior.AllowGet);
Cyril Gandon
  • 16,830
  • 14
  • 78
  • 122
user2633804
  • 187
  • 1
  • 3
  • 15

2 Answers2

5

You can have your dataV2 class (which i would advice to change its name to something more meaningful) have a double? nullable field instead of a double. That way, you won't have to duplicate your object for cases where there is "value" field in the JSON:

public class SomeData
{
    public string Time { get; set; }
    public double? Value { get; set; }

    public SomeData(string time, double? value)
    {
        this.time = time;   
        this.value = value;   
    }

    public SomeData() { }
}

And then deserializing it:

SomeData data = JsonConvert.DeserializeObject<SomeData>(json, 
                            new JsonSerializerSettings 
                            { NullValueHandling = NullValueHandling.Ignore });
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • it retrieves {"time":"1.0","value":6},{"time":"1.2","value":null},{"time":"1.4","value":8} and it should retrieve {"time":"1.0","value":6},{"xValue":"1.2" },{"time":"1.4","value":8} – user2633804 Apr 16 '15 at 09:52
  • The json result retrieves a value null and when the value doesn't exists in db it should only retrieve the time field. – user2633804 Apr 16 '15 at 09:55
  • 1
    @user2633804 I've edited my answer. You can ignore nulls by setting `NullValueHandling.Ignore` and passing them to the `DeserializeObject` method. Use that when you serialize your object back to a JSON. – Yuval Itzchakov Apr 16 '15 at 09:59
  • 1
    @user2633804 inheritance should solve it... alternative you can put it in a List though you would have code duplication.. – Florian Schmidinger Apr 16 '15 at 09:59
  • @FlorianSchmidinger I think even inheritance is redundant for that problem, he simply doesn't want to serialize nulls. – Yuval Itzchakov Apr 16 '15 at 10:00
  • @YuvalItzchakov but he has a mvc controller and would have to use json.net additional here... – Florian Schmidinger Apr 16 '15 at 10:02
  • @FlorianSchmidinger He can [work around](http://stackoverflow.com/questions/13294211/mvc4-action-returning-jsonresult-without-null) that. But i guess it's a small price to pay. – Yuval Itzchakov Apr 16 '15 at 10:04
1

You could inherit dataV1 by dataV2 ... then you can put them in a List<dataV1> :

public class ChartDataFactory //whatever... or directly in the controller though i don't recommend it
{
    public static IEnumerable<dataV1> GetChartData() //parameters ommited
    {
        List<dataV1> result = new List<dataV1>();

        //initialze connection/command/reader

        while (sqlReader.Read())
        {
            if (sqlReader["value"] != DBNull.Value) 
            {
                result.Add(new dataV1((string)sqlReader["time"]));
            }
            else
            {
                result.Add(new dataV2((string)sqlReader["time"],(double)sqlReader["value"]));
            }
        }
        // tear down connection
        return result;
    }
}


public class dataV1
{
    public string time { get; set; }

    public dataV1(string Ptime)
    {
        this.time = Ptime;
    }

    public dataV1() { }
}

public class dataV2 : dataV1
{
    public double value { get; set; }

    public dataV2(string Ptime, double Pvalue):base(Ptime)
    {
        this.value = Pvalue;
    }

    public dataV2() { }
}
Florian Schmidinger
  • 4,682
  • 2
  • 16
  • 28