Background
Coming from PowerShell background, while learning ASP.NET Core based development I wanted to wrap my head around how to handle JSON, so ended up taking notes on how to do this in C# and as an exercise convert those into PowerShell code snippets for my reference.
In my explorations I like using the dotnet-script global tool for interactive user experience with C# and PowerShell core (which is already an interactive shell). So, you will see that I mostly use C# script files (.csx) and PowerShell script files (.ps1).
Giving the credit where it’s due, I followed this tutorial to learn JSON handling in C# and made these notes of my own.
In this post the topics covered are:
- Parsing JSON
- Enumerating JSON
System.Text.Json
This is the new namespace in .NET core which provides the API to work with JSON.
JSON parsing
JSON parsing is basically reading the JSON data and converting it into a JsonDocument
typed object in C#.
Long story short:
- Use the static method
Parse
on theJsonDocument
class to consume a JSON string and get an object back. RootElement
on the instance ofJsonDocument
gives you the entire JSON object- Root element if it contains array can be indexed
- To get the value of a property on the JSON object use
GetProperty('propertyName')
Below are the contents of a test.csx file.
#!/usr/bin/env dotnet-script
using System;
using System.Text.Json;
string data = " [ {\"name\": \"John Doe\", \"occupation\": \"gardener\"}, " +
"{\"name\": \"Peter Novak\", \"occupation\": \"driver\"} ]";
// using statement is used to dispose of the JsonDocument object later
// Parse static method parses the JSON string and returns a JsonDocument instance
using (JsonDocument doc = JsonDocument.Parse(data))
{
var root = doc.RootElement; // RootElement is the real object we are after
var user1 = root[0]; // since our object contains an array, we can index into it
var user2 = root[2];
// Use the method GetProperty() to get properties of the JsonElement object
Console.WriteLine(user1.GetProperty("name")); // GetProperty()
Console.WriteLine(user2.GetProperty("name"));
}
To do the same in PowerShell, below are the contents of a test.ps1 file.
#!/usr/bin/env pwsh
using namespace System.Text.Json
$data = '[{"name": "John Doe", "occupation": "gardener"},' +
'{"name": "Peter Novak", "occupation": "driver"} ]';
$doc = [JsonDocument]::Parse($data)
$root = $doc.RootElement
$user1 = $root[0]
$user2 = $root[1]
Write-Host $User1.GetProperty("name")
Write-Host $User2.GetProperty("name")
# dispose the JsonDocument once done
# We don't do this in C# coz of the using statement automatically doing this
$doc.Dispose()
JSON Enumerate
In the above example we indexed into the elements of the array directly and then used GetProperty()
this only works if you know the number of elements in advance along with property names, but there are better ways to iterate and enumerate.
Trick for someone new is to remember:
- Enumerating arrays to fetch different items
- Enumerating objects to fetch properties.
#!/usr/bin/env dotnet-script
using System;
using System.Text.Json;
string data = " [ {\"name\": \"John Doe\", \"occupation\": \"gardener\"}, " +
"{\"name\": \"Peter Novak\", \"occupation\": \"driver\"} ]";
using (var doc = JsonDocument.Parse(data))
{
JsonElement root = doc.RootElement;
// call method EnumerateArray() to iterate over items in the array
foreach (var user in root.EnumerateArray())
{
Console.WriteLine("====== User details ====");
// EnumerateObject() method is used return an ObjectEnumerator
// which is then used to get the Name & Value pair for each property
foreach (var prop in user.EnumerateObject())
{
Console.WriteLine($"{prop.Name} -> {prop.Value}");
}
}
}
Doing the same in PowerShell makes it easier to grasp.
#!/usr/bin/env pwsh
using namespace System.Text.Json
$data = "[ {`"name`": `"John Doe`", `"occupation`": `"gardener`"}, " +
"{`"name`": `"Peter Novak`", `"occupation`": `"driver`"} ]";
$doc = [JsonDocument]::Parse($data)
$root = $doc.RootElement
foreach ($user in $root.EnumerateArray()) {
Write-Host "====== User details ===="
foreach ($property in $user.EnumerateObject()) {
Write-Host $("{0} -> {1}" -f $property.Name, $property.Value)
}
}
Conclusion 🗞
In my continued efforts to learn C# language and take some of the learnings back to PowerShell, I realized that though the JSON cmdlets provide a lot of ease working with JSON, there are other ways to skin the cat.
There will be a follow up post on this soon…