0

I got some Json, that looks like this:

[
  {
    "starttime": "2020-02-27T14:30:00Z",
    "endtime": "2020-02-27T14:40:00Z"
  },
  {
    "Temp": {
      "value": 3
    },
    "Pressure": {
      "value": 29
    },
    "Humidity": {
      "value": 85
    }
  }
]

I would like to deserialize it onto a object on the form:

public class Sample {
   public string Name {get; set;}
   public int Value {get;set;}
}

and then get 3 instances where name is set to either Temp, Pressure, Humidity, and Value set to 3, 29, 85 I don't really care about the start-/endtime part.

Any help would be greatly appreciated...

/Søren

Update:

Came up with this myself:

var tmp = JsonConvert.DeserializeObject<JArray>(content);

var samples = tmp.
    SelectMany(x => ((JToken) x).Children())
    .Where(x => !((JProperty) x).Name.Contains("time"))
    .Select(x =>
    {
        var tmp2 = x.First.ToObject<Sample>();
        tmp2.name = ((JProperty) x).Name;
        return tmp2;
    })
    .ToList();

but I think Pavel's solution below, is more readable....

1

3 Answers 3

1

You can use Json.Linq to get a list of Sample objects from your json. Parse json to JArray instance, then enumerate all properties of the last object to get the names and values

var array = JArray.Parse(json);

var samples = ReadSamples(array.Last());
foreach (var sample in samples)
{
    Console.WriteLine($"{sample.Name} {sample.Value}");
}

IEnumerable<Sample> ReadSamples(JToken data)
{
    foreach (JProperty item in data)
    {
        yield return new Sample()
        {
            Name = item.Name,
            Value = item.Value["value"]?.Value<int>() ?? 0
        };
    }
}

The output will be the following

Temp 3
Pressure 29
Humidity 85

It's also possible to do the same using System.Text.Json API, which is available from .NET Core 3.x

Sign up to request clarification or add additional context in comments.

Comments

0

Per your posted JSON, you would get a model like below. Use http://json2csharp.com/#

public class Temp
{
    public int value { get; set; }
}

public class Pressure
{
    public int value { get; set; }
}

public class Humidity
{
    public int value { get; set; }
}

public class RootObject
{
    public DateTime starttime { get; set; }
    public DateTime endtime { get; set; }
    public Temp Temp { get; set; }
    public Pressure Pressure { get; set; }
    public Humidity Humidity { get; set; }
}

4 Comments

And for smolesen: the point here is - use something like the above to interpret the data, then write code to reshape it into a model of your preferred shape afterwards
There's really no need to use that website: Visual Studio (and other IDEs) have a "paste JSON as classes" feature built in; put JSON in the clipboard, and let the IDE generate types that work with it. Similarly for XML too.
I think most of you is missing the point, that the number of types (Temp, Pressure, Humidity) can change dynamically, and I don't want to go change the code each time a new "type" is added., That's also why my datasample class is generic, with a name/type property.
@smolesen It wasn't clear from the question. Why do you think two of the three answers suggested using classes? The title of the question also simply says Deserialize Json into C#, which is vague. We don't know that you need a dynamic solution unless you specifiy that in the question. As helpful as SO is, at the end of the day we can't read minds.
0

If your JSON is not dynamic, creating classes which model your JSON is a good idea.

An easy way is to Copy JSON to clipboard -> Open Visual Studio -> Edit -> Paste Special -> Paste JSON as classes.

This should give you the following classes:

public class Class1
{
    public DateTime starttime { get; set; }
    public DateTime endtime { get; set; }
    public Temp Temp { get; set; }
    public Pressure Pressure { get; set; }
    public Humidity Humidity { get; set; }
}

public class Temp
{
    public int value { get; set; }
}

public class Pressure
{
    public int value { get; set; }
}

public class Humidity
{
    public int value { get; set; }
}

And now you can deserialize the JSON array to List<Class1>using the Newtonsoft.Json NuGet package:

using Newtonsoft.Json;
using System.Collections.Generic;

...

string json = @"[
  {
    ""starttime"": ""2020 - 02 - 27T14: 30:00Z"",
    ""endtime"": ""2020-02-27T14:40:00Z""
  },
  {
    ""Temp"": {
      ""value"": 3
    },
    ""Pressure"": {
      ""value"": 29
    },
    ""Humidity"": {
      ""value"": 85
    }
  }
]";

var myObject = JsonConvert.DeserializeObject<List<Class1>>(json);

2 Comments

The idea was to NOT have a class for each type (since I don't know the number of types)
@smolesen Hence why I said this solution is only suitable for non dynamic JSON.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.