using System.Collections.Generic;
using Newtonsoft.Json.Linq;
public static void Main()
List<Foo> foos = new List<Foo>
Name = "A foo with a car",
Name = "A foo holding a profile",
DateCreated = DateTime.UtcNow
string json = JsonConvert.SerializeObject(foos, Formatting.Indented);
[JsonConverter(typeof(DynamicPropertyNameConverter))]
public int Id { get; set; }
public string Name { get; set; }
[JsonPropertyNameByType("Vehicle", typeof(Vehicle))]
[JsonPropertyNameByType("Profile", typeof(Profile))]
public object Item { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public int Year { get; set; }
public string AccountName { get; set; }
public DateTime DateCreated { get; set; }
[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
class JsonPropertyNameByTypeAttribute : Attribute
public string PropertyName { get; set; }
public Type ObjectType { get; set; }
public JsonPropertyNameByTypeAttribute(string propertyName, Type objectType)
PropertyName = propertyName;
public class DynamicPropertyNameConverter : JsonConverter
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
Type type = value.GetType();
JObject jo = new JObject();
foreach (PropertyInfo prop in type.GetProperties().Where(p => p.CanRead))
string propName = prop.Name;
object propValue = prop.GetValue(value, null);
JToken token = (propValue != null) ? JToken.FromObject(propValue, serializer) : JValue.CreateNull();
if (propValue != null && prop.PropertyType == typeof(object))
JsonPropertyNameByTypeAttribute att = prop.GetCustomAttributes<JsonPropertyNameByTypeAttribute>()
.FirstOrDefault(a => a.ObjectType.IsAssignableFrom(propValue.GetType()));
propName = att.PropertyName;
public override bool CanRead
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
throw new NotImplementedException();
public override bool CanConvert(Type objectType)