I am new to programming and to C#. I'm using Visual Studio (latest) to write my app.
This is a console app that is attempting to read a log (text) file where each line is a separate JSON entry.
This is what a single item JSON entry looks like:
{
"timestamp": "2022-02-09T07:05:59Z",
"event": "Color",
"Hex": "#FFFF00",
"Name": "Yellow"
}
I establish the full path to the text file and store it in a string 'fileFullPath' and I'm 'using System.Text.Json'.
Each entry in the text file always has two fields - 'timestamp' and 'event'. I created a base class called 'LogHeader':
namespace LogModels
{
public class LogHeader
{
public string TimeStamp { get; set; }
public string Event { get; set; }
}
}
Then, I created a class for each event and inherited from LogHeader:
public class Color : LogHeader
{
public string Hex { get; set;}
public string Name { get; set;}
}
Next, I read the file and start going through each line and writing to the console using a switch statement based on the 'event' field:
foreach (string line in File.ReadAllLines(fileFullPath))
{
var logHeader = JsonSerializer.Deserialize<LogHeader>(line,options);
switch (logHeader.Event)
{
case "Color":
var eventColor = JsonSerializer.Deserialize<LogModels.Event.Color>(line, options);
Console.WriteLine($"The color is {eventColor.Name}.");
Console.WriteLine($"The Hex value is {eventColor.Hex}.");
break;
}
The console output is:
The color is Yellow.
The Hex value is #FFFF00.
The problem comes in with the nested JSON objects, which look like this:
{
"timestamp": "2022-02-09T07:07:52Z",
"event": "Carpet",
"Shag": [
{
"Color": "Green",
"Count": 3
},
{
"Color": "Black",
"Count": 104
}
],
"Pile": [
{
"Color": "Blue",
"Count": 5
},
{
"Color": "Beige",
"Count": 13
}
],
"Outdoor": [
{
"Color": "Pebble",
"Count": 300
},
{
"Color": "Astroturf",
"Count": 12
}
]
}
At this point, I'm lost. I've tried creating a class called "Carpet" with child classes called "Shag", "Pile", etc. I've tried creating separate classes for each of the subtypes.
The desired outcome is for this to appear on the console:
Shag Carpet -
Green: 3
Black: 104
Pile Carpet -
Blue: 5
Beige: 13
Outdoor Carpet -
Pebble: 300
Astroturf: 12
I can't imagine this is as hard to do as I'm making it out to be, but I can't seem to find any examples to help me through it.
Also, I've only posted to this site a couple of times, and I'm not sure of the proper structure of replying to suggestions, etc.
Thank you for your help with this.
CodePudding user response:
Since you are new to programming and to C#, I highly recommend you to use Newtonsoft.Json serializer.
You can try this code
Data data = JsonConvert.DeserializeObject<Data>(json);
classes
public class Data
{
[JsonProperty("timestamp")]
public DateTime TimeStamp { get; set; }
[JsonProperty("event")]
public string Event { get; set; }
public string Hex { get; set; }
public string Name { get; set; }
public List<ColourCount> Shag { get; set; }
public List<ColourCount> Pile { get; set; }
public List<ColourCount> Outdoor { get; set; }
}
public class ColourCount
{
public string Color { get; set; }
public int Count { get; set; }
}
you can test using reflection
var props = data.GetType().GetProperties();
foreach (var prop in props)
{
if (!prop.PropertyType.IsCollectible)
{
if(prop.GetValue(data)!=null)
Console.WriteLine($" {prop.Name} : { prop.GetValue(data).ToString()} ");
}
else
{
Console.WriteLine($" { prop.Name} - ");
var items = prop.GetValue(data) as IList<ColourCount>;
foreach (var item in items)
{
Console.WriteLine($" {item.Color} : {item.Count}");
}
}
}
result
TimeStamp : 2022-02-09 7:07:52 AM
Event : Carpet
Shag -
Green : 3
Black : 104
Pile -
Blue : 5
Beige : 13
Outdoor -
Pebble : 300
Astroturf : 12
if you still want to use Text.Json change property name attribute
Data data = System.Text.Json.JsonSerializer.Deserialize<Data>(json);
public class Data
{
[JsonPropertyName("timestamp")]
public DateTime TimeStamp { get; set; }
[JsonPropertyName("event")]
public string Event { get; set; }
.....
}