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 class WeeklySalesData
public WeeklySalesData(string weekName, DateTime date, decimal totalSales)
this.weekName = weekName;
this.totalSales = totalSales;
public string WeekName { get { return weekName; } }
public DateTime Date { get { return date; } }
public decimal TotalSales { get { return totalSales; } }
public class ConstructorConverter<T> : JsonConverter
public override bool CanConvert(Type objectType)
return typeof(T) == objectType;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
throw new NotImplementedException();
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
var contract = serializer.ContractResolver.ResolveContract(value.GetType()) as JsonObjectContract;
throw new JsonSerializationException(string.Format("Type {0} does not correspond to a JSON object.", value.GetType()));
writer.WriteStartConstructor(value.GetType().Name);
foreach (var provider in contract.GetConstructorParameterValueProviders())
serializer.Serialize(writer, provider.GetValue(value));
writer.WriteEndConstructor();
public static partial class JsonExtensions
internal static IEnumerable<IValueProvider> GetConstructorParameterValueProviders(this JsonObjectContract contract)
return contract.CreatorParameters.Select(p => contract.GetConstructorParameterValueProvider(p)).ToArray();
internal static IValueProvider GetConstructorParameterValueProvider(this JsonObjectContract contract, JsonProperty parameter)
if (parameter.ValueProvider != null)
return parameter.ValueProvider;
var property = contract.Properties.GetClosestMatchProperty(parameter.PropertyName);
var provider = property == null ? null : property.ValueProvider;
throw new JsonSerializationException(string.Format("Cannot get IValueProvider for {0}", parameter));
public static void Test()
var data = new WeeklySalesData("2018W1", new DateTime(2019, 2, 15, 0, 0, 0, DateTimeKind.Utc), 1100);
var settings = new JsonSerializerSettings
Converters = { new JavaScriptDateTimeConverter(), new ConstructorConverter<WeeklySalesData>() },
var json = JsonConvert.SerializeObject(new [] { data }, Formatting.Indented, settings);
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: ");