简体   繁体   中英

Returning JSON Array of Objects in C#

These are the classes I have which represent the way I want the data to be shown to the end user:

    namespace PHCTimeSeriesInsights.API.Models
{
    public class ProductTimeSeries
    {
        public List<DeviceTimeSeries> DeviceTimeSeries { get; set; }
        public string DeviceId { get; set; }
    }

    public class DeviceTimeSeries
    {
        public DateTime TimeStamp { get; set; }
        public Double MeasuredValue { get; set; }
        public string DateField { get; set; }


    }
}

I want the output in the following format: Here the string 8787887 is an actual value of a device;

{
        "8787887":[ 
        {
        "prop":"val", 
        "prop":"val"
        },
       {
       "prop":"val1", 
       "prop":"val2"
}
    ]
    }

I've this snippet representing what I did but it does not give me an optimal format:

List<ProductTimeSeries> prd = new List<ProductTimeSeries>();
            prd.Add(new ProductTimeSeries
            {
                DeviceId = getTelemetry.PropertyName,
                DeviceTimeSeries = deviceIdTimeSeries
            });

This is the result that I get:

[
    {
        "deviceTimeSeries": [
            {
                "timeStamp": "2019-07-19T17:44:55.856Z",
                "measuredValue": 6.98,
                "dateField": "7/19/2019"
            },
            {
                "timeStamp": "2019-07-19T17:45:58.697Z",
                "measuredValue": 7.04,
                "dateField": "7/19/2019"
            }
        ],
        "deviceId": "deviceId"
    }
]

What changes do I have to make to the format in the way I want?

Instead of using classes, in C# you want to actually use a Dictionary. In your case, it should work by using a Dictionary<string, List<DeviceTimeSeries>> where the string is your “DeviceId”.

See the example below.

https://dotnetfiddle.net/luE1Z4

Which in sort runs

Console.WriteLine("Dictionary Test");
var productTimeSeries2 = new Dictionary<string, IList<DeviceTimeSeries>> () {
    {
        "DeviceId-888",
        new List < DeviceTimeSeries > () {
            new Program.DeviceTimeSeries() {
                TimeStamp = DateTime.Now,
                MeasuredValue = 2,
                DateField = "7/29/2019"
            }
        }
    }
};
Console.WriteLine(JsonConvert.SerializeObject(productTimeSeries2));

And outputs

{  
   "DeviceId-888":[  
      {  
         "TimeStamp":"2019-07-31T20:45:28.677905+00:00",
         "MeasuredValue":2.0,
         "DateField":"7/29/2019"
      }
   ]
}

List prd

needs to be

Dictionary> prd

then your object should serialize to your desired format.

It's not clear what you want to put in the values of prop and value

But I believe the upshot is you will have to use some sort of custom code to write out your structure. Below I use a custom JsonConverter from Json.Net

public class CustomJsonConverter : JsonConverter
{
    private readonly Type[] _types;

    public CustomJsonConverter(params Type[] types)
    {
        _types = types;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        JToken t = JToken.FromObject(value);

        if (t.Type != JTokenType.Object)
        {
            t.WriteTo(writer);
        }
        else
        {
            JObject o = (JObject)t;
            IList<string> propertyNames = o.Properties().Select(p => p.Name).ToList();

            JObject root = new JObject();

            JObject props = JObject.Parse(@"{""prop"" : ""A"", ""value"":""B""}");
            root.AddFirst(new JProperty(o["DeviceId"].Value<object>().ToString(), props));


            root.WriteTo(writer);
        }
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter.");
    }

    public override bool CanRead
    {
        get { return false; }
    }

    public override bool CanConvert(Type objectType)
    {
        return _types.Any(t => t == objectType);
    }
}

Then, serialize your object using the custom converter

DeviceTimeSeries d = new DeviceTimeSeries { TimeStamp = DateTime.Now, MeasuredValue = 1.23, DateField = "01/01/1970" };
        ProductTimeSeries p = new ProductTimeSeries();
        List<DeviceTimeSeries> dts = new List<DeviceTimeSeries>();
        dts.Add(d);

        p.DeviceTimeSeries = dts;
        p.DeviceId = "8787887";

        string json = JsonConvert.SerializeObject(p, Formatting.Indented, new CustomJsonConverter(typeof(ProductTimeSeries)));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM