我尝试使用Json.net序列化LinearGradientBrush
(System.Windows.Media.LinearGradientBrush)但没有成功:
var lg = new LinearGradientBrush();
lg.StartPoint = new Point(2,3);
lg.EndPoint = new Point(3.1,0);
lg.GradientStops = new GradientStopCollection(new []{ new GradientStop(Colors.Red, 0),new GradientStop(Colors.White, 1)});
var json = JsonConvert.SerializeObject(lg);
此代码将输出一个包含"System.Windows.Media.LinearGradientBrush"
的字符串,这显然是错误的。
我尝试使用xml序列化,它按预期工作:
var sb = new StringBuilder();
var writer = XmlWriter.Create(sb, new XmlWriterSettings(){ Indent=true});
var ser = new XmlSerializer(lg.GetType(), new []{ typeof(System.Windows.Media.MatrixTransform)});
ser.Serialize(writer,lg);
var xml = sb.ToString();
为什么json序列化程序无法序列化LinearGradientBrush?
答案 0 :(得分:3)
库Json.NET
在尝试序列化复杂对象时遇到一些问题,例如an array,LinearGradientBrush对象或具有高级结构的对象,如字典或类似的东西(在这种情况下)一个LinearGradientBrush,有一个GradientStopCollection数据结构可能是你问题的原因。)
尝试按照documentation中的建议,以更加可控的方式序列化您的对象。
如果这没有帮助,可能就是为您的对象创建自定义转换器,如建议here和use it,同时调用方法SerializeObject()
进行序列化你的对象。
答案 1 :(得分:1)
旧问题,但仍与最新的Json.NET相关。
您可以选择仅将画笔序列化为XAML。这意味着你最终会在你的JSON文件中使用XAML,但这是我能想到的最干净的解决方案。
在画笔上方,使用JsonConvert注释:
[JsonConverter(typeof(BrushJsonConverter))]
public Brush Brush {get; set;}
并实现以下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);
}
}
编辑:如果您更喜欢使用纯JSON,还可以将XAML序列化为JSON。这可能会降低性能,但它确实会产生更整洁的结果
/// <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);
}
}