2017-02-01 7 views
2

私はUnity3DでJson.NET(v90r1)のNet20ライブラリを使用していますが、Json.NETを使用して型のフィールドをシリアル化しようとしています。Json.NETでFormatterAssemblyStyle.SimpleでType型のフィールドをシリアライズ

私は、FormatterAssemblyStyleが自動的に生成されたタイプ情報に影響を与えることがありますが、タイプタイプのフィールドには影響しないようです。たとえば:

using Newtonsoft.Json; 
using System.Runtime.Serialization.Formatters; 
using UnityEngine; 

public class Example : MonoBehaviour 
{ 
    void Start() 
    { 
     var settings = new JsonSerializerSettings() { 
      Formatting = Formatting.Indented, 
      TypeNameHandling = TypeNameHandling.All, 
      TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple, 
     }; 

     Debug.Log(JsonConvert.SerializeObject(new Foo(), settings)); 
    } 
} 

public class Foo 
{ 
    public System.Type type = typeof(void); 
} 

は、この次のようなJSON文字列になります:あなたが見ることができるように

{ 
    "$type": "Foo, Assembly-CSharp", 
    "type": "System.Void, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
} 

FormatterAssemblyStyle.Simple$typeのために使用されてきたが、FormatterAssemblyStyle.Fulltypeのために使用されてきました。

これは私の所望の出力です:

{ 
    "$type": "Foo, Assembly-CSharp", 
    "type": "System.Void, mscorlib" 
} 

は、どのように私は両方のタイプが同じように印刷するのですか?ほとんどの検索結果は、プライベートメンバーのシリアライズやクラスのシリアライズに関連するため、タイプの情報ではなく、のタイプがのタイプのシリアル化であるため、答えを見つけることができませんでした。

答えて

2

sourcesによると:オブジェクト型がType型である

internal static bool TryConvertToString(object value, Type type, out string s) 
{ 
    //... 
    type = value as Type; 
    if (type != null) 
    { 
     s = type.AssemblyQualifiedName; 
     return true; 
    } 
    //... 
} 

場合はTypeのカスタムコンバータを作成する​​例に従うことができますしかし、それはType.AssemblyQualifiedName

としてフォーマットされます:

public class TypeConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     if (typeof(System.Type).IsAssignableFrom(value.GetType())) 
     { 
      // here you decide how much information you really want to dump 
      Type type = (Type)value; 
      writer.WriteValue(type.FullName + ", " + type.Assembly.GetName().Name); 
     } 
     else 
     { 
      JToken t = JToken.FromObject(value); 
      t.WriteTo(writer); 
     } 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     throw new NotImplementedException("Unnecessary because CanRead is false. The type will skip the converter."); 
    } 

    public override bool CanRead 
    { 
     get { return false; } 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return typeof(System.Type).IsAssignableFrom(objectType); 
    } 
} 

と同じように使用してください:

var settings = new JsonSerializerSettings() 
    { 
     Formatting = Formatting.Indented, 
     TypeNameHandling = TypeNameHandling.All, 
     TypeNameAssemblyFormat = FormatterAssemblyStyle.Simple, 
     Converters = { new TypeConverter() } 
    }; 

    Console.WriteLine(JsonConvert.SerializeObject(new Foo(), settings)); 
関連する問題