using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using System.Text.Json.Serialization;
public static partial class JsonExtensions
public static JsonElement? Get(this JsonElement element, string name) =>
element.ValueKind != JsonValueKind.Null && element.ValueKind != JsonValueKind.Undefined && element.TryGetProperty(name, out var value)
? value : (JsonElement?)null;
public static JsonElement? Get(this JsonElement element, int index)
if (element.ValueKind == JsonValueKind.Null || element.ValueKind == JsonValueKind.Undefined)
return index < element.GetArrayLength() ? element[index] : null;
public static void Test()
""id"": ""gid://shopify/Product/4534543543316"",
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": ""gid://shopify/ProductImage/146345345339732""
Console.WriteLine("Testing JSON with keys present:");
Console.WriteLine("\nTesting JSON with keys missing:");
""id"": ""gid://shopify/Product/4534543543316"",
""originalSrc"": ""https://cdn.shopify.com/s/files/1/0286/pic.jpg"",
""id"": ""gid://shopify/ProductImage/146345345339732""
static void TestGood(string raw)
var doc = JsonSerializer.Deserialize<JsonElement>(raw);
Assert.Throws<KeyNotFoundException>(() => doc.GetProperty("does-not-exist"));
var node = doc.Get("data")?.Get("products")?.Get("edges")?[0].Get("node");
Assert.AreEqual(null, doc.Get("data")?.Get("XXXXproducts")?.Get("edges")?[0].Get("node"));
Assert.AreEqual(null, doc.Get("data")?.Get("products")?.Get("XXXedges")?[0].Get("node"));
Assert.AreEqual(null, doc.Get("data")?.Get("products")?.Get("edges")?[0].Get("XXXnode"));
static void Test(string raw)
var doc = JsonSerializer.Deserialize<JsonElement>(raw);
Assert.Throws<KeyNotFoundException>(() => doc.GetProperty("does-not-exist"));
var node = doc.Get("data")?.Get("products")?.Get("edges")?.Get(0)?.Get("node");
var productIdString = node?.Get("id")?.GetString();
var originalSrcString = node?.Get("featuredImage")?.Get("originalSrc")?.GetString();
Int64? someIntegerValue = node?.Get("Size")?.GetInt64();
Console.WriteLine("productIdString={0}, originalSrcString={1}, someIntegerValue={2}", productIdString, originalSrcString, someIntegerValue);
var arrayDoc = JsonSerializer.Deserialize<JsonElement>(arrayJson);
Assert.AreEqual(0, arrayDoc.Get(0).Value.GetInt32());
Assert.IsNull(arrayDoc.Get(1));
Assert.Throws<IndexOutOfRangeException>(() => arrayDoc.Get(-1));
public static partial class JsonExtensions
public static JsonElement? Get(this JsonDocument doc, string name) => doc.RootElement.Get(name);
public static JsonElement? Get(this JsonDocument doc, int index) => doc.RootElement.Get(index);
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , GetNetCoreVersion());
Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Assembly.GetName().Name, typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public static string GetNetCoreVersion()
var assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
var assemblyPath = assembly.Location.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];