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;
public class DefaultValueContractResolver : DefaultContractResolver
readonly Dictionary<Type, DefaultValueHandling> overrides;
public DefaultValueContractResolver(IEnumerable<KeyValuePair<Type, DefaultValueHandling>> overrides) : base()
throw new ArgumentNullException("overrides");
this.overrides = overrides.ToDictionary(p => p.Key, p => p.Value);
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
var property = base.CreateProperty(member, memberSerialization);
if (property.DefaultValueHandling == null)
DefaultValueHandling handling;
if (overrides.TryGetValue(property.PropertyType, out handling))
property.DefaultValueHandling = handling;
public class PartnerLoginOptions
public string Username { get; set; }
public string Password { get; set; }
public string DeviceModel { get; set; }
public string Version { get; set; }
public bool? IncludeUrls { get; set; }
public bool? ReturnDeviceType { get; set; }
public bool? ReturnUpdatePromptVersions { get; set; }
public static void Test()
var resolver = new DefaultValueContractResolver(
new Dictionary<Type, DefaultValueHandling>
{ typeof(bool?), DefaultValueHandling.Ignore }
NamingStrategy = new CamelCaseNamingStrategy()
var settings = new JsonSerializerSettings { ContractResolver = resolver };
Test(settings, typeof(bool?));
var settings2 = new JsonSerializerSettings
ContractResolver = new DefaultValueContractResolver(new Dictionary<Type, DefaultValueHandling> { { typeof(string), DefaultValueHandling.Ignore } })
NamingStrategy = new CamelCaseNamingStrategy()
Test(settings2, typeof(string));
private static void Test(JsonSerializerSettings settings, Type typeToExclude)
Console.WriteLine("Testing exclusion of default values of type {0}:", typeToExclude);
var options = new PartnerLoginOptions
var json = JsonConvert.SerializeObject(options, Formatting.Indented, settings);
IEqualityComparer comparer = EqualityComparer<object>.Default;
foreach (var property in options.GetType().GetProperties().Where(p => p.PropertyType == typeToExclude))
var value = property.GetValue(options);
var defaultValue = GetDefault(property.PropertyType);
var isDefault = comparer.Equals(value, defaultValue);
var contains = json.IndexOf("\"" + property.Name + "\"", StringComparison.OrdinalIgnoreCase) >= 0;
Assert.IsTrue(isDefault != contains);
public static object GetDefault(Type type)
return Activator.CreateInstance(type);
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.CodeBase.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
return assemblyPath[netCoreAppIndex + 1];