C# Json.net LinearGradientBrush序列化

C# Json.net LinearGradientBrush序列化,c#,json.net,lineargradientbrush,C#,Json.net,Lineargradientbrush,我试图用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 Gradie

我试图用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?

json.NET
在尝试序列化复杂对象(如LinearGradientBrush对象或具有高级结构的对象,如字典等)时遇到一些问题(对于LinearGradientBrush,GradientStopCollection数据结构可能是问题的原因)

尝试以更可控的方式序列化对象,如中所建议的


如果这没有帮助,那么可能是在调用方法
SerializeObject()时,按照建议为对象创建自定义转换器
用于对象的序列化。

Json.NET
在尝试序列化复杂对象(如LinearGradientBrush对象或具有高级结构的对象,如字典等)时遇到一些问题(对于LinearGradientBrush,GradientStopCollection数据结构可能是问题的原因)

尝试以更可控的方式序列化对象,如中所建议的


如果这样做没有帮助,可能需要按照建议为对象创建自定义转换器,同时调用方法
SerializeObject()
对对象进行序列化。

旧问题,但仍然与最新的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);
    }
}
//
///将笔刷存储为XAML,因为Json.net无法将其保存为Json
/// 
公共类BrushJsonConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
var jo=newjobject{{“value”,XamlWriter.Save(value)};
写作工作(作家);
}
public override object ReadJson(JsonReader reader,Type objectType,object existingValue,
JsonSerializer(序列化程序)
{
//从流中加载作业对象
var jObject=jObject.Load(读卡器);
返回XamlReader.Parse(jObject[“value”].ToString());
}
公共覆盖布尔CanConvert(类型objectType)
{
返回类型(画笔)。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);
    }
}
//
///通过将画笔临时序列化为XAML来存储画笔,因为Json.NET有问题
///将其保存为JSON
/// 
公共类BrushJsonConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
//将笔刷转换为XML节点
var doc=新的XmlDocument();
doc.LoadXml(XamlWriter.Save(value));
//将XML节点序列化为JSON
var jo=JObject.Parse(JsonConvert.SerializeXmlNode(doc.DocumentElement));
写作工作(作家);
}
public override object ReadJson(JsonReader reader,Type objectType,object existingValue,
JsonSerializer(序列化程序)
{
//从流中加载作业对象
var jObject=jObject.Load(读卡器);
//将JSON节点序列化为XML
var xml=JsonConvert.DeserializeXmlNode(jObject.ToString());
返回XamlReader.Parse(xml.InnerXml);
}
公共覆盖布尔CanConvert(类型objectType)
{
返回类型(画笔)。IsAssignableFrom(objectType);
}
}

老问题,但仍然与最新的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);
    }
}
//
///将笔刷存储为XAML,因为Json.net无法将其保存为Json
/// 
公共类BrushJsonConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
var jo=newjobject{{“value”,XamlWriter.Save(value)};
写作工作(作家);
}
public override object ReadJson(JsonReader reader,Type objectType,object existingValue,
JsonSerializer(序列化程序)
{
//从流中加载作业对象
var jObject=jObject.Load(读卡器);
返回XamlReader.Parse(jObject[“value”].ToString());
}
公共覆盖布尔CanConvert(类型objectType)
{
返回类型(画笔)。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);
    }
}
//
///通过将画笔临时序列化为XAML来存储画笔,因为Json.NET有问题
///将其保存为JSON
/// 
公共类BrushJsonConverter:JsonConverter
{
公共重写void WriteJson(JsonWriter编写器、对象值、JsonSerializer序列化器)
{
//将笔刷转换为XML节点
var doc=新的XmlDocument();
doc.LoadXml(XamlWriter.Save(value));
//将XML节点序列化为JSON
var jo=JObject.Parse(JsonConvert.SerializeXmlNode(doc.DocumentElement));
写作工作(作家);
}
公共重写对象ReadJson(JsonReader,类型objectTyp