0

I have looked at several solutions over the web on reading nested json files but I haven't found one suitable to my need. Maybe because I am new to JSON. Here is my issue:

I have the following JSON in a file:

{
  "ConfigError" : {
    "DateSent": "2022-04-28T14:03:16.6628493-07:00",
    "ToolType": "WSM",
    "IsSent": true
  },

  "FileCopyError" : {
    "DateSent": "2022-06-14T14:03:16.6628493-07:00",
    "ToolType": "RMT",
    "IsSent": false
  }
}

For this I have written two classes. One for the Inner object:

public class SummaryEmailStatus
    {
        public DateTime DateSent { get; set; }
        public string ToolType { get; set; }
        public bool IsSent { get; set; }
    }

One for the Outer Objects:

public class SummaryEmailClass
    {
        SummaryEmailStatus Status { get; set; } = new SummaryEmailStatus();
    }

I would like to be able to read the JSON in C#. I'm primarily concerned with the inner objects. They are of same class but they need to be used differently. So ideally I'd want a function that I can pass in "ConfigError" or "FileCopyError" into and it will return SummaryEmailStatus class object populated by the values in the JSON:

public static void ReadJasonFile(string jsonFileName, string objctName)
        {
            List<SummaryEmailClass> emailClassList = new List<SummaryEmailClass>();
            dynamic jsonFile = JsonConvert.DeserializeObject(File.ReadAllText(jsonFileName));
            SummaryEmailStatus sumclass = jsonFile[objctName];
        }

But this gives me a run time error saying:

Cannot implicitly convert type "Newtonsoft.Json.Linq.JObject to SummaryEmailStatus

How can I successfully parse out the inner summaryemailstatus objects?

Additionally, I'd like to be able to create the JSON data within C#. The reason being, when I read the JSON, I will do some task and then will need to update the values of the JSON with the current timestamps. I'd imagine, I'd need to rewrite the file. How can I write a nested JSON like this in C#?

If JSON is not the best way to do this, I am open to alternatives

Datboydozy
  • 131
  • 7

3 Answers3

2

you can try

string json = File.ReadAllText(jsonFileName);

Dictionary<string,SummaryEmailStatus> summaryEmailStatus = 
JsonConvert.DeserializeObject<Dictionary<string,SummaryEmailStatus>>(json);

you can use it

SummaryEmailStatus configError =   summaryEmailStatus["ConfigError"];

if you want update data

summaryEmailStatus["ConfigError"].DateSent= DateTime.Now;

and serialize back

json = JsonConvert.SerializeObject(summaryEmailStatus);

or if you have only 2 main properties, create a class

public class SummaryEmailClass
    {
        SummaryEmailStatus ConfigError { get; set; } 
        SummaryEmailStatus FileCopyError{ get; set; } 
    }

and use it

SummaryEmailClass summaryEmailStatus = 
JsonConvert.DeserializeObject<SummaryEmailStatusClass>(json);

SummaryEmailStatus configError =   summaryEmailStatus.ConfigError;
Serge
  • 40,935
  • 4
  • 18
  • 45
  • For the second part of my question, how might I be able to create this nested JSON data in C#? That is after I have read the JSON and need to update it? – Datboydozy Jun 14 '22 at 19:42
  • I just incorporated it into my main big code and it works flawlessly. I just marked your answer as solution. Thank you so much! – Datboydozy Jun 14 '22 at 21:31
1

Summary

You need to convert your JObject into the type you are expecting, as shown here:

SummaryEmailStatus sumclass = jsonFile[objctName].ToObject<SummaryEmailStatus>();

Details

jsonFile[objtName] is of type JObject. The reason is because JsonConvert.DeserializeObject has no idea that you intend to convert that into a list of SummaryEmailStatus.

Once you have your array of JObjects, you can convert that into a SummaryEmailStatus as shown in the following snippet:

public static void ReadJasonFile(string jsonFileName, string objctName)
{
    List<SummaryEmailClass> emailClassList = new List<SummaryEmailClass>();
    dynamic jsonFile = JsonConvert.DeserializeObject(File.ReadAllText(jsonFileName));
    SummaryEmailStatus sumclass = jsonFile[objctName].ToObject<SummaryEmailStatus>();
}
Victor Chelaru
  • 4,491
  • 3
  • 35
  • 49
  • That explanation makes sense thank you! For the second part however, how might I be able to create this nested JSON data in C#? After I read the JSON, I'd need to update the JSON with data I calculated in the program. The update needs to be written like the nested source it read from. – Datboydozy Jun 14 '22 at 19:44
1

Easy way is kept both objects in JSON, I rewrite your code and add root. For example, if you want to write Config Error and don't write File Copy Error, you can save one of them like null.

public class ConfigError
{
    public DateTime DateSent { get; set; }
    public string ToolType { get; set; }
    public bool IsSent { get; set; }
}

public class FileCopyError
{
    public DateTime DateSent { get; set; }
    public string ToolType { get; set; }
    public bool IsSent { get; set; }
}

public class Root
{
    public ConfigError ConfigError { get; set; }
    public FileCopyError FileCopyError { get; set; }
}

//in your method to get all data
var json = File.ReadAllText(jsonFileName);
var myDeserializedClass = JsonConvert.DeserializeObject<Root>(json);

Example change config and write to file

var json = @"{
  ""ConfigError"" : {
    ""DateSent"": ""2022-04-28T14:03:16.6628493-07:00"",
    ""ToolType"": ""WSM"",
    ""IsSent"": true
  },

  ""FileCopyError"" : {
    ""DateSent"": ""2022-06-14T14:03:16.6628493-07:00"",
    ""ToolType"": ""RMT"",
    ""IsSent"": false
  }
}";

var conf = JsonConvert.DeserializeObject<Root>(json);
conf.ConfigError.DateSent = DateTime.Now;
conf.ConfigError.ToolType = "New way";
conf.ConfigError.IsSent = false;
conf.FileCopyError = null;
var newJson = JsonConvert.SerializeObject(conf);
File.WriteAllText("your path", newJson);
Bushuev
  • 557
  • 1
  • 10
  • 29
  • Thank you, this addresses my first question. How can I achieve the second part which is writing this back to a JSON in C#? When I read the data, I'll need to use it then update the time stamp write it into JSON. How can I write this? – Datboydozy Jun 14 '22 at 20:02
  • 1
    @Datboydozy, I added the example with changing data and write to file. – Bushuev Jun 14 '22 at 20:10