using System.Collections.Generic;
using Newtonsoft.Json.Serialization;
public static void Main()
var data = new ProductData()
Console.WriteLine("PCD Only");
Console.WriteLine(Serialize(data, new[] { XProductDataSource.PCD }));
Console.WriteLine("\n\nMetadata Only");
Console.WriteLine(Serialize(data, new[] { XProductDataSource.Metadata }));
Console.WriteLine("\n\nPCD + Metadata Only");
Console.WriteLine(Serialize(data, new[] { XProductDataSource.Metadata, XProductDataSource.PCD }));
static string Serialize(object obj, IEnumerable<XProductDataSource> sources)
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new XProductDataSourceResolver(sources);
return JsonConvert.SerializeObject(obj, settings);
public class XProductDataSourceResolver : DefaultContractResolver
private readonly HashSet<XProductDataSource> _sourcesToInclude;
public XProductDataSourceResolver(IEnumerable<XProductDataSource> sources)
_sourcesToInclude = new HashSet<XProductDataSource>(sources);
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
var propertiesToInclude = type
x => x.GetCustomAttributes()
.OfType<XProductDataSourceAttribute>()
.Any(sourceAttribute => _sourcesToInclude.Contains(sourceAttribute.Source)));
var properties = base.CreateProperties(type, memberSerialization);
.Where(p => propertiesToInclude.Any(info => info.Name == p.UnderlyingName))
public class XProductDataSourceAttribute : Attribute
public XProductDataSource Source { get; private set; }
public XProductDataSourceAttribute(XProductDataSource source)
public enum XProductDataSource
[XProductDataSource(XProductDataSource.PCD)]
public string ProductId { get; set; }
[XProductDataSource(XProductDataSource.Metadata)]
public string ProductTitle { get; set; }