using System.Collections.Generic;
using Newtonsoft.Json.Serialization;
public static void Main(string[] args)
List<Foo> list = new List<Foo>
Enum = VagueLocation.Eveywhere,
String = "bada boom bada bing",
JsonSerializerSettings settings = new JsonSerializerSettings
ContractResolver = new CustomResolver(),
Formatting = Formatting.Indented
Console.WriteLine("----- Serialize -----");
string json = JsonConvert.SerializeObject(list, settings);
Console.WriteLine("----- Deserialize -----");
list = JsonConvert.DeserializeObject<List<Foo>>(json, settings);
foreach (Foo foo in list)
private static void DumpFoo(Foo foo)
foreach (PropertyInfo pi in typeof(Foo).GetProperties())
Console.WriteLine(pi.Name + ": " + pi.GetValue(foo));
public int Id { get; set; }
public int Int { get; set; }
public bool IntSpecified { get; set; }
public bool Bool { get; set; }
public bool BoolSpecified { get; set; }
public decimal Decimal { get; set; }
public bool DecimalSpecified { get; set; }
public DateTime Date { get; set; }
public bool DateSpecified { get; set; }
public string String { get; set; }
public bool StringSpecified { get; set; }
public VagueLocation Enum { get; set; }
public bool EnumSpecified { get; set; }
enum VagueLocation { Nowhere, Here, There, Eveywhere };
public class CustomResolver : DefaultContractResolver
const string IndicatorKeyword = "Specified";
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
Dictionary<string, JsonProperty> dict = props.ToDictionary(p => p.UnderlyingName);
foreach (JsonProperty prop in props)
string name = prop.UnderlyingName;
if (name.Length > IndicatorKeyword.Length && name.EndsWith(IndicatorKeyword))
string targetName = name.Substring(0, name.Length - IndicatorKeyword.Length);
JsonProperty coProp = null;
if (dict.TryGetValue(targetName, out coProp))
PropertyInfo realTarget = type.GetProperty(targetName);
PropertyInfo realIndicator = type.GetProperty(name);
coProp.ValueProvider = new CustomValueProvider(realTarget, realIndicator);
class CustomValueProvider : IValueProvider
PropertyInfo targetProperty;
PropertyInfo indicatorProperty;
public CustomValueProvider(PropertyInfo targetProperty, PropertyInfo indicatorProperty)
this.targetProperty = targetProperty;
this.indicatorProperty = indicatorProperty;
public object GetValue(object target)
bool isSpecified = (bool)indicatorProperty.GetValue(target);
return isSpecified ? targetProperty.GetValue(target) : null;
public void SetValue(object target, object value)
bool isSpecified = value != null;
indicatorProperty.SetValue(target, isSpecified);
if (isSpecified) targetProperty.SetValue(target, value);