1

我试图LinearGradientBrush用 Json.net 序列化 (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?

4

2 回答 2

3

该库Json.NET在尝试序列化复杂对象时存在一些问题,例如数组、LinearGradientBrush 对象或具有高级结构的对象,例如 Dictionary 或类似的东西(在 LinearGradientBrush 的情况下,有一个 GradientStopCollection 数据结构可能是你的问题的原因)。

尝试按照文档中的建议以更可控的方式序列化您的对象。

如果这没有帮助,也许是按照此处的建议为您的对象创建一个自定义转换器,并在调用对象序列化方法时使用它。SerializeObject()

于 2014-01-13T16:19:37.113 回答
3

老问题,但仍然与最新的 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);
    }
}
于 2016-07-02T11:44:08.540 回答