2012-12-10 10 views
8

JSON.Netを使用して構造体をシリアル化/逆シリアル化すると、ビルドイン構造体の型(System.Drawing.Sizeなど)は文字列にシリアル化されますが、カスタム構造体の型はJSONオブジェクトにシリアル化されます。例えばJSON.Net構造体のシリアル化の不一致

using System; 
using System.Drawing; 
using Newtonsoft.Json; 

namespace TestJsonNet 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Console.WriteLine(JsonConvert.SerializeObject(new Size(50, 50))); 
      Console.WriteLine(JsonConvert.SerializeObject(new Size2(50, 50))); 
     } 
    } 

    struct Size2 
    { 
     public int Width { get; set; } 
     public int Height { get; set; } 
     public Size2(int w, int h) : this() 
     { 
      Width = w; Height = h; 
     } 
    } 
} 

出力以下:メモリレイアウトは常に同じであるため

"50, 50" 
{"Width":50,"Height":50} 

私は、文字列に構造体をシリアル化の考え方を理解することができます。しかし、なぜカスタム構造体を直列化する際に相違がありますか?

また、JSON.Netに後者のような構造体(JSONではなく文字列)をシリアル化するようにしたいと思います(内部的な理由から)。それが可能なら、どのように達成できますか?

+1

私はこの記事を見つけた[JSON.NETシリアライゼーショントラブル](http://stackoverflow.com/questions/9750836/json-net-serialization-trouble)しかし、私はまだ、すべての構造体型がこのような振る舞いをしないようにしたいと考えています。 –

答えて

2

反射を使用すると、この問題を解決できます。 自分が提案したソリューションに参加し、プロパティ名と値を取得するためにリフレクションを使用しました。

class StructConverter : JsonConverter 
{ 
    public override void WriteJson(
     JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var myObject = (object)value; 
     var jObject = new JObject(); 

     Type myType = myObject.GetType(); 
     IList<PropertyInfo> props = new List<PropertyInfo>(myType.GetProperties()); 

     foreach (PropertyInfo prop in props) 
     { 

      jObject.Add(prop.Name, prop.GetValue(myObject, null).ToString()); 
     } 
     serializer.Serialize(
      writer, jObject); 
    } 

....

public override bool CanConvert(Type objectType) 
    { 
     return objectType.IsValueType; 
    } 
} 
+0

私の質問に対する本当の答えは、あなたができないことです。 TypeConverterの代わりに独自のコンバータを使用するようにJSON.NETを設定する方法はありません。しかし、それはおそらく最も一般的なので、私はあなたに小切手(とネクロマンサーバッジ?)を与えます。 –

+0

ありがとうDave。 JSONシリアライザがあるかどうか疑問に思います。 –

+0

はい、あります。 ServiceStack.Textを見てください。構造体にParseとToStringの2つの関数を提供する場合は、逆シリアル化とシリアライズを行うためにそれらを使用します。私はそれが非常に便利だと思う。 – jruizaranguren

関連する問題