using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
public interface IJobModel
string ClientBaseURL { get; set; }
string UserEmail { get; set; }
ExportType Type { get; set; }
List<IItemModel> Items { get; set; }
public interface IItemModel
string ImageSize { get; set; }
string ImagePpi { get; set; }
List<ICamSettings> CamSettings { get; set; }
public interface ICamSettings
string FileName { get; set; }
public class ThumbnailJobModel : IJobModel
[JsonProperty("clientBaseURL")]
public string ClientBaseURL { get; set; }
[JsonProperty("userEmail")]
public string UserEmail { get; set; }
[JsonConverter(typeof(ExportTypeConverter))]
public ExportType Type { get; set; }
[JsonProperty("items", ItemConverterType = typeof(ConcreteConverter<IItemModel, Item>))]
public List<IItemModel> Items { get; set; }
public ThumbnailJobModel()
Type = ExportType.Thumbnails;
Items = new List<IItemModel>();
public class Item : IItemModel
public string Id { get; set; }
[JsonProperty("imageSize")]
public string ImageSize { get; set; }
[JsonProperty("imagePpi")]
public string ImagePpi { get; set; }
[JsonProperty("shoots", ItemConverterType = typeof(ConcreteConverter<ICamSettings, ShootSettings>))]
public List<ICamSettings> CamSettings { get; set; }
CamSettings = new List<ICamSettings>();
public class ShootSettings : ICamSettings
[JsonProperty("orientation")]
[JsonConverter(typeof(StrictStringEnumConverter))]
public Orientation Orientation { get; set; }
[JsonProperty("clothShape")]
[JsonConverter(typeof(StrictStringEnumConverter))]
public Shape Shape { get; set; }
[JsonProperty("fileName")]
public string FileName { get; set; }
Orientation = Orientation.Perspective;
public class ConcreteConverter<IInterface, TConcrete> : JsonConverter where TConcrete : IInterface
public override bool CanConvert(Type objectType)
return typeof(IInterface) == objectType;
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue, JsonSerializer serializer)
return serializer.Deserialize<TConcrete>(reader);
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
throw new NotImplementedException();
public class ExportTypeConverter : StringEnumConverter
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
return ExportType.Thumbnails;
public override bool CanConvert(Type objectType)
return objectType == typeof(ExportType);
public class StrictStringEnumConverter : StringEnumConverter
public StrictStringEnumConverter() { this.AllowIntegerValues = false; }
public static void HandleDeserializationError(object sender, Newtonsoft.Json.Serialization.ErrorEventArgs errorArgs)
errorArgs.ErrorContext.Handled = true;
var currentObj = errorArgs.CurrentObject as ShootSettings;
if (currentObj == null) return;
currentObj.Orientation = Orientation.Perspective;
currentObj.Shape = Shape.Folded;
public static void Test()
string jobConfig = GetJson();
IJobModel m_jobModel = JsonConvert.DeserializeObject<ThumbnailJobModel>(jobConfig);
var json2 = JsonConvert.SerializeObject(m_jobModel, Formatting.Indented);
Console.WriteLine("\nDeserialied and re-serialized JSON: ");
Console.WriteLine(json2);
""clientBaseURL"":""https://clientName.fr"",
""userEmail"":""myName@gmail.com"",
""imageSize"":""1280,720"",
""fileName"":""front1.png"",
""orientation"":""front"",
""clothShape"":""hanger""
""fileName"":""folded1.png"",
""orientation"":""front"",
""clothShape"":""folded""
""fileName"":""right1.png"",
""orientation"":""right"",
""clothShape"":""hanger""
""imageSize"":""1280,720"",
""fileName"":""perspective1.png"",
""orientation"":""perspective""
public static void Main()
Console.WriteLine("Environment version: " + Environment.Version);
Console.WriteLine("Json.NET version: " + typeof(JsonSerializer).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public class AssertionFailedException : System.Exception
public AssertionFailedException() : base() { }
public AssertionFailedException(string s) : base(s) { }
public static class Assert
public static void IsTrue(bool value)
public static void IsTrue(bool value, string message)
throw new AssertionFailedException(message ?? "failed");