using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
namespace Windows.Data.Json
public interface IJsonValue
string Stringify() => ToString();
public class JsonObject : IJsonValue
System.Json.JsonObject obj;
protected JsonObject(System.Json.JsonObject obj) => this.obj = obj ?? throw new ArgumentNullException();
public override string ToString() => obj.ToString();
public static JsonObject Parse(string json) => new JsonObject((System.Json.JsonObject)System.Json.JsonValue.Parse(json));
public class JsonArray : IJsonValue
System.Json.JsonArray obj;
protected JsonArray(System.Json.JsonArray obj) => this.obj = obj ?? throw new ArgumentNullException();
public override string ToString() => obj.ToString();
public static JsonArray Parse(string json) => new JsonArray((System.Json.JsonArray)System.Json.JsonValue.Parse(json));
public class JsonValue : IJsonValue
System.Json.JsonValue obj;
protected JsonValue(System.Json.JsonValue obj) => this.obj = obj;
public override string ToString() => obj == null ? "null" : obj.ToString();
public static JsonValue Parse(string json) => new JsonValue(json == null ? null : (System.Json.JsonValue)System.Json.JsonValue.Parse(json));
public class LightStageCommand { }
public class SmartphoneCommand { }
public class ImageDataModel
public JsonObject CaptureResultData { get; }
public SmartphoneCommand SmartphoneCommand { get; }
public LightStageCommand LightStageCommand { get; }
public string TimeStamp { get; }
ImageDataModel(JsonObject captureResultData, LightStageCommand lightStageCommand, SmartphoneCommand smartphoneCommand, string timeStamp)
this.CaptureResultData = captureResultData;
this.SmartphoneCommand = smartphoneCommand;
this.LightStageCommand = lightStageCommand;
this.TimeStamp = timeStamp;
public ImageDataModel(string _captureResultData, LightStageCommand _lightStageCommand, SmartphoneCommand _smartphoneCommand)
CaptureResultData = JsonObject.Parse(_captureResultData);
SmartphoneCommand = _smartphoneCommand;
LightStageCommand = _lightStageCommand;
TimeStamp = DateTime.Now.ToString("HH:mm.ss, dd. MM. yyyy");
public class WindowsDataJsonObjectConverter : WindowsDataJsonConverterBase<Windows.Data.Json.JsonObject>
public override JsonObject ReadJson(JsonReader reader, Type objectType, JsonObject existingValue, bool hasExistingValue, JsonSerializer serializer) =>
JsonObject.Parse(reader.ReadOuterJson(dateParseHandling: DateParseHandling.None));
public class WindowsDataJsonArrayConverter : WindowsDataJsonConverterBase<Windows.Data.Json.JsonArray>
public override JsonArray ReadJson(JsonReader reader, Type objectType, JsonArray existingValue, bool hasExistingValue, JsonSerializer serializer) =>
JsonArray.Parse(reader.ReadOuterJson(dateParseHandling: DateParseHandling.None));
public class WindowsDataJsonValueConverter : WindowsDataJsonConverterBase<Windows.Data.Json.JsonValue>
public override JsonValue ReadJson(JsonReader reader, Type objectType, JsonValue existingValue, bool hasExistingValue, JsonSerializer serializer) =>
JsonValue.Parse(reader.ReadOuterJson(dateParseHandling: DateParseHandling.None));
public abstract class WindowsDataJsonConverterBase<TJsonValue> : JsonConverter<TJsonValue> where TJsonValue : IJsonValue
public override void WriteJson(JsonWriter writer, TJsonValue value, JsonSerializer serializer) =>
writer.WriteRawValue(value.Stringify());
public static partial class JsonExtensions
public static string ReadOuterJson(this JsonReader reader, Formatting formatting = Formatting.None, DateParseHandling? dateParseHandling = null, FloatParseHandling? floatParseHandling = null)
var oldDateParseHandling = reader.DateParseHandling;
var oldFloatParseHandling = reader.FloatParseHandling;
if (dateParseHandling != null)
reader.DateParseHandling = dateParseHandling.Value;
if (floatParseHandling != null)
reader.FloatParseHandling = floatParseHandling.Value;
using (var sw = new StringWriter(CultureInfo.InvariantCulture))
using (var jsonWriter = new JsonTextWriter(sw) { Formatting = formatting })
jsonWriter.WriteToken(reader);
reader.DateParseHandling = oldDateParseHandling;
reader.FloatParseHandling = oldFloatParseHandling;
public static void Test()
TestSimpleRoundTrip(JsonObject.Parse("{}"));
TestSimpleRoundTrip(JsonArray.Parse("[]"));
TestSimpleRoundTrip(JsonArray.Parse(@"[1,2,""three""]"));
TestSimpleRoundTrip(JsonValue.Parse(@"""three"""));
TestSimpleRoundTrip(JsonValue.Parse(@"1"));
TestSimpleRoundTrip(JsonValue.Parse(@"null"));
static void TestSimpleRoundTrip<TJsonValue>(TJsonValue value) where TJsonValue : IJsonValue
var settings = new JsonSerializerSettings()
Converters = { new WindowsDataJsonObjectConverter(), new WindowsDataJsonArrayConverter(), new WindowsDataJsonValueConverter() },
var json = JsonConvert.SerializeObject(value, settings);
var value2 = JsonConvert.DeserializeObject<TJsonValue>(json, settings);
Assert.AreEqual(value.Stringify(), value2.Stringify());
public static void TestImageDataModel()
foreach (var json in GetJson())
var imageDataModel = new ImageDataModel(json, new LightStageCommand(), new SmartphoneCommand());
var settings = new JsonSerializerSettings
Converters = {new WindowsDataJsonObjectConverter()},
var newJson = JsonConvert.SerializeObject(imageDataModel, Formatting.Indented, settings);
Console.WriteLine(newJson);
var newModel = JsonConvert.DeserializeObject<ImageDataModel>(newJson, settings);
Assert.AreEqual(imageDataModel.TimeStamp, newModel.TimeStamp);
Assert.AreEqual(imageDataModel.CaptureResultData.ToString(), newModel.CaptureResultData.ToString());
static IEnumerable<string> GetJson()
""SKU"": ""BOWS-SMALL-ALFIE""
""SKU"": ""BOWS-LARGE-ALONZO""
""SKU"": ""BOWS-LARGE-CLANCY""
""SKU"": ""BOWS-SMALL-ALVIN""
""SKU"": ""BOWS-SMALL-CLARK""
""SKU"": ""BOWS-SMALL-ALVIN""
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];