1

LinearGradientBrushJson.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 に関連しています。

ブラシを 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 に答える
3

array、 LinearGradientBrush オブジェクト、 Dictionary などの高度な構造を持つオブジェクトなどの複雑なオブジェクトをシリアル化しようとすると、ライブラリJson.NETにいくつかの問題があります (LinearGradientBrush の場合、GradientStopCollection データ構造があり、あなたの問題の原因)。

ドキュメントで提案されているように、より制御された方法でオブジェクトをシリアル化してみてください。

これで問題が解決しない場合は、ここで提案されているように、オブジェクトのカスタム コンバーターを作成し、オブジェクトのシリアル化のメソッドを呼び出すときにそれを使用する場合があります。SerializeObject()

于 2014-01-13T16:19:37.113 に答える