3

Suppose I have a nested json file which looks like this:

[{"toplevel":{"firstleveldata":{"id":12345,"no":123}},"secondleveldata":{"fruit":{"apples":"y"},"veg":{"small":{"gree":{"fresh":{"available":3}}}}},"thirdleveldata":{"fruit":{"changes":[{"itemid":1,"subno":1,"green":[],"red":[{"extraid":2,"element":5}]}]}}}]

and the following R code which can parse the it to a nice data.frame except for the last one (if that can be fixed to that's a bonus)

what would be neat altenative using C# look like? It's not something i've ever coded in before so wouldn't know where to start.

The end goal being to export the nested JSON into a csv, multiple csvs with primary / foreign keys to merge on of necessary.

R code for context.

library(jsonlite)

library(tidyverse)

fun <- function(x)
       {list(
#keys
id = pluck(x,"toplevel","firstleveldata","id", .default = NA),
no = pluck(x,"toplevel","firstleveldata","no", .default = NA),

apples = pluck(x,"secondleveldata","fruit","apples", .default = NA),
itemid = pluck(x,"toplevel","thirdleveldata","fruit","changes","itemid", .default = NA) #doesn't work)}

out<-map_df(list.files("my_json_file",full.names=TRUE),~map_df(fromJSON(txt=., simplifyVector=FALSE), fun))

out

Thanks

Mikey
  • 165
  • 1
  • 14

1 Answers1

4

A quick way to explore this structure and get started with json in C# is to copy the json packet as you expect it to be. Taking what you have in your question as an example, copy the json into the clipboard and create a new C# code file and write your default namespace only as follows:

namespace Data
{
    // Next step will be here
}

After that, place your cursor between the curly braces, click the edit menu, then paste special, JSON as Classes

This will generate some classes for you that match the JSON schema you have. In this case, there's a Class1 because it cannot determine the name of the object with the toplevel, secondlevel etc properties. You can give it a more meaningful name for your case.

Update for .NET 5.0 and later versions

Following the release of .NET 5.0, a new namespace now comes out of the box that can handle JSON as easily as Newtonsoft and in a performant way.

The simplest way to parse the Json into your objects will be with a one liner as follows...

var items = JsonSerializer.Deserialize<IEnumerable<MyItem>>(jsonData);

For this to work, you'll need to have the following in your usings...

using System.Collections.Generic; // For IEnumerable<T>
using System.Text.Json;           // For JsonSerializer.*

Following is the original answer that used the Newtonsoft.Json Nuget package. That still works with .NET 5.0 but I've included the new namespace for those who would wish to avoid including an extra DLL that has functionality that is covered out of the box.

Original method using Newtonsoft.Json

Open the package manager console (if you can't see it in VS, press Ctrl+Q and type "Package Manager Console"). In the package manager, type the following

Install-Package Newtonsoft.Json

after ensuring that you have your solution saved and specifying the project you want to add that package to as your default project as in the screenshot:

Screenshot of Package Manager Console with default project selected and highlighted.

and wait for it to complete. You'll now have the ability to deserialize JSON you have into your classes. Go to where you want to do the processing and type the following...

// at the top of the file...
using Newtonsoft.Json;

// where you need to decode it...
string jsonData = GetYourJsonDataFromAFileOrAPICall(); // replace with how you get the json
var items = JsonConvert.DeserializeObject<IEnumerable<MyItem>>(jsonData);

At this point, you'll have an IEnumerable<MyItem> (MyItem is what I renamed Class1) representing your json. You can change that to be a list, or array if you want a more specific collection.

Fabulous
  • 2,393
  • 2
  • 20
  • 27
  • PM> Install-Package Newtonsoft.Json Install-Package : Project 'Default' is not found. At line:1 char:1 + Install-Package Newtonsoft.Json + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Default:String) [Install-Package], ItemNotFoundException + FullyQualifiedErrorId : NuGetProjectNotFound,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand I've tried https://stackoverflow.com/questions/10130333/cant-install-packages-with-nuget-500-internal-server-error – Mikey Aug 21 '18 at 16:11
  • When running that command, ensure that you have the project you wish to add the package to selected. I'll update my answer to reflect that. And it appears the question you linked to is based on a different problem (a server issue at the time of asking) – Fabulous Aug 23 '18 at 08:50