0

I'm trying to port the last piece of code I have that is dependent on Newtonsoft.Json to System.Text.Json.

The code parses a JSON fragment and flattens it. This is generated by a legacy system so we'd rather not change that if possible.

// Comment here including the person who last made a change to the program
[
  // Comment here with the date this value set was changed
  [ "value1", "value2", "value3" ],
  // Comment here with the date this value set was changed
  [ "value1", "value2", "value3" ],
  // Repeat over and over for all data
]

I have been parsing this for Newtonsoft.Json using the following code:

using (var sr = new StreamReader(stream))
{
    var array = JArray.Parse(sr.ReadToEnd());
    var flattened = array.SelectMany(x => x).ToArray();

    foreach (var item in flattened)
        items.Add(item.ToObject<string>());
}

The code above pulls each of the values that are within the JSON payload and puts them into a list called items.

How can I parse JSON in the format above using System.Text.Json?

Sam
  • 4,219
  • 7
  • 52
  • 80
  • What are you asking us? – Enigmativity Nov 25 '21 at 21:44
  • @Enigmativity I thought it was fairly straight forward, however I have added a question mark at the end – Sam Nov 25 '21 at 22:09
  • You're asking us to write the code for you. That's usually frowned upon. Can you show us the attempt you've made and where you're stuck with that attempt? – Enigmativity Nov 25 '21 at 22:16
  • Also, when asking for code to be written, it's a good idea to provide us much supporting code as possible. In this case, it would be great to get copy, paste, and run code that we can see `Newtonsoft.Json` in action along with the expected output from your input. – Enigmativity Nov 25 '21 at 22:19
  • Try this: `var fin = JsonSerializer.Deserialize(jsonDataAsString).SelectMany(x => x);` – Andy Nov 25 '21 at 22:25
  • @Enigmativity I legit don't think you actually read this post. Two points: The question, I thought was fairly to the point and concise. Secondly, you ask for supporting code... I literally have the exact code I'm trying to rewrite above. – Sam Nov 27 '21 at 01:58
  • @Andy thanks, that's exactly what I was looking for. If you'd like to add an answer I'll accept it. – Sam Nov 27 '21 at 02:12
  • @Sam - You didn't ask a question. You told us a story of what you're trying to do without asking a question. Second, your code isn't complete. What is `items`? – Enigmativity Nov 27 '21 at 02:39
  • @Enigmativity -- I think his question is *How can I parse JSON in the format above using System.Text.Json?* Currently he is using `Newtonsoft.Json`, but wants to port it to `System.Text.Json`. He wasn't sure how to load this up and have it parse the data the same way as it was in the previous JSON library. `List` looks like it would be a `List` as he is deserializing arrays of strings, also it shows him using `ToObject()`. – Andy Nov 27 '21 at 02:43
  • @Andy - Yes, most likely that's what it is, but the OP **didn't specifically ask** so we could only assume, and, if the OP wanted us to write the whole method, then it's starting to be a code writing service. This isn't a good question as far as this site goes. – Enigmativity Nov 27 '21 at 02:49

2 Answers2

1

To translate your code from Newtonsoft.Json to System.Txt.Json, you want to do the following:

Firstly, I see you are reading from a stream. So, I am going to dump your example to a JSON file as-is. Then I will read it in to a stream. I am also making this async:

using (var stream = File.OpenRead("test.json"))
{
    var multiDimentional = await JsonSerializer.DeserializeAsync<string[][]>(
        stream, new JsonSerializerOptions
    {
        AllowTrailingCommas = true,
        ReadCommentHandling = JsonCommentHandling.Skip
    });

    var myArray = multiDimentional.SelectMany(x => x);

    foreach(var i in myArray)
    {
        Console.WriteLine(i);
    }
}

This will output:

value1
value2
value3
value1
value2
value3

Since your example had comments and trailing commas, I added exceptions for those scenarios.

If you don't need this async, then simply remove the await and change DeserializeAsync to Deserialize, and instead of reading from the stream, you'll have to read it to a string first. So:

var jsonAsString = File.ReadAllText("test.json");

var multiDimentional = JsonSerializer.Deserialize<string[][]>(
    jsonAsString, new JsonSerializerOptions
{
    AllowTrailingCommas = true,
    ReadCommentHandling = JsonCommentHandling.Skip
});

var myArray = multiDimentional.SelectMany(x => x);

foreach(var i in myArray)
{
    Console.WriteLine(i);
}
Andy
  • 12,859
  • 5
  • 41
  • 56
0

Do you mean something like this?

var data = JsonSerializer.Deserialize<List<List<string>>>(jsonString, new JsonSerializerOptions { AllowTrailingCommas = true });

var flattenData = data.SelectMany(item => item).ToList();
Mucksh
  • 160
  • 5