Old question but still relevant with the latest Json.NET.
You can opt to only serialize the brush as XAML. This means you'll end up with XAML in your JSON file but it's the cleanest solution I could come up with.
Above your brush, use the JsonConvert annotation:
[JsonConverter(typeof(BrushJsonConverter))]
public Brush Brush {get; set;}
And implement the following JsonConverter:
/// <summary>
/// Stores a brush as XAML because Json.net has trouble saving it as JSON
/// </summary>
public class BrushJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var jo = new JObject {{"value", XamlWriter.Save(value)}};
jo.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
// Load JObject from stream
var jObject = JObject.Load(reader);
return XamlReader.Parse(jObject["value"].ToString());
}
public override bool CanConvert(Type objectType)
{
return typeof(Brush).IsAssignableFrom(objectType);
}
}
EDIT: If you prefer to have pure JSON, you can also serialize the XAML to JSON. This may degrade performance but it does make for a tidier result
/// <summary>
/// Stores a brush by temporarily serializing it to XAML because Json.NET has trouble
/// saving it as JSON
/// </summary>
public class BrushJsonConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// Turn the brush into an XML node
var doc = new XmlDocument();
doc.LoadXml(XamlWriter.Save(value));
// Serialize the XML node as JSON
var jo = JObject.Parse(JsonConvert.SerializeXmlNode(doc.DocumentElement));
jo.WriteTo(writer);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
// Load JObject from stream
var jObject = JObject.Load(reader);
// Seriaze the JSON node to XML
var xml = JsonConvert.DeserializeXmlNode(jObject.ToString());
return XamlReader.Parse(xml.InnerXml);
}
public override bool CanConvert(Type objectType)
{
return typeof(Brush).IsAssignableFrom(objectType);
}
}