using System.Collections;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public class VersionObjectConverter : JsonConverter<Version>
public VersionObjectConverter() : this(false) { }
public VersionObjectConverter(bool serializeAsObject) { this.SerializeAsObject = serializeAsObject; }
static readonly Newtonsoft.Json.Converters.VersionConverter InnerConverter = new Newtonsoft.Json.Converters.VersionConverter();
bool SerializeAsObject { get; set; }
public int Major; public int Minor; public int Build = -1; public int Revision = -1; public Int16 MajorRevision = -1; public Int16 MinorRevision = -1;
public Version ToVersion()
return new Version(Major, Minor);
return new Version(Major, Minor, Build);
return new Version(Major, Minor, Build, Revision);
public override void WriteJson(JsonWriter writer, Version value, JsonSerializer serializer)
else if (SerializeAsObject)
serializer.Serialize(writer, new VersionDto { Major = value.Major, Minor = value.Minor, Build = value.Build, Revision = value.Revision, MajorRevision = value.MajorRevision, MinorRevision = value.MinorRevision});
InnerConverter.WriteJson(writer, value, serializer);
public override Version ReadJson(JsonReader reader, Type objectType, Version existingValue, bool hasExistingValue, JsonSerializer serializer)
switch (reader.MoveToContentAndAssert().TokenType)
case JsonToken.Null: return null;
case JsonToken.String: return (Version)InnerConverter.ReadJson(reader, objectType, hasExistingValue ? existingValue : null, serializer);
case JsonToken.StartObject: return serializer.Deserialize<VersionDto>(reader).ToVersion();
default: throw new JsonSerializationException(string.Format("Unknown token type {0}", reader.TokenType));
public static partial class JsonExtensions
public static JsonReader MoveToContentAndAssert(this JsonReader reader)
throw new ArgumentNullException("reader");
if (reader.TokenType == JsonToken.None)
while (reader.TokenType == JsonToken.Comment)
public static JsonReader ReadAndAssert(this JsonReader reader)
throw new ArgumentNullException("reader");
throw new JsonReaderException("Unexpected end of JSON stream.");
public static void Test()
var version = new Version(1, 2, 3, 0);
var settings = new JsonSerializerSettings
Converters = { new VersionObjectConverter(serializeAsObject : true) },
var reportJSON = JsonConvert.SerializeObject(version, settings);
var report2 = JsonConvert.DeserializeObject<Version>(reportJSON, settings)!;
var reportJSON2 = JsonConvert.SerializeObject(report2, settings);
Assert.That(reportJSON == "{\"Major\":1,\"Minor\":2,\"Build\":3,\"Revision\":0,\"MajorRevision\":0,\"MinorRevision\":0}");
Assert.That(report2 == version);
Console.WriteLine(reportJSON);
string defaultVersionJson = JsonConvert.SerializeObject(version);
var report3 = JsonConvert.DeserializeObject<Version>(defaultVersionJson, settings)!;
Assert.That(defaultVersionJson == "\"1.2.3.0\"");
TestRoundTrip(new Version(1, 2, 3, 4), false);
TestRoundTrip(new Version(1, 2, 3, 4), true);
TestRoundTrip(new Version(1, 2, 3), false);
TestRoundTrip(new Version(1, 2, 3), true);
TestRoundTrip(new Version(1, 2), false);
TestRoundTrip(new Version(1, 2), true);
static void TestRoundTrip(Version version, bool serializeAsObject)
var settings = new JsonSerializerSettings
Converters = { new VersionObjectConverter(serializeAsObject : serializeAsObject) },
string reportJSON = "/* Comment */ " + JsonConvert.SerializeObject(version, settings) + " /* Comment */";
Version report2 = JsonConvert.DeserializeObject<Version>(reportJSON, settings);
Assert.That(report2 == version, "report2 == version");
var json2 = JsonConvert.SerializeObject(report2, settings);
var report3 = JsonConvert.DeserializeObject<Version>(json2, settings);
Assert.That(report3 == version, "report3 == version");
var flippedSettings = new JsonSerializerSettings
Converters = { new VersionObjectConverter(serializeAsObject : serializeAsObject) },
var json3 = JsonConvert.SerializeObject(report2, flippedSettings);
var report4 = JsonConvert.DeserializeObject<Version>(json3, settings);
Assert.That(report4 == version, "report3 == version");
Console.WriteLine("JSON round-tripped successfully: {0}", reportJSON);
public static void Main()
Console.WriteLine("Environment version: {0} ({1}), {2}", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version, Environment.OSVersion);
Console.WriteLine("{0} version: {1}", typeof(JsonSerializer).Namespace, typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");