2013-10-14 7 views
19

特定のタイプのオブジェクトをシリアル化するときに、JSONにタイプ名のプロパティを設定したいとします。 私は、コンバータを書いた:Newtonsoft.Jsonを使用して、型情報でjsonにオブジェクトをシリアル化する方法は?

public class TypeInfoConverter : JsonConverter { 
    private readonly IEnumerable<Type> _types; 

    public TypeInfoConverter(IEnumerable<Type> types) { 
     Contract.Requires(types != null); 

     _types = types; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { 
     var jObject = JObject.FromObject(value, serializer); 
     jObject.AddFirst(new JProperty("Type", value.GetType().Name)); 
     jObject.WriteTo(writer); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { 
     return serializer.Deserialize(reader, objectType); 
    } 

    public override bool CanConvert(Type objectType) { 
     return _types.Any(t => t.IsAssignableFrom(objectType)); 
    } 
} 

しかし、私は、オブジェクトをシリアル化しようとしている私はここに無限再帰があります var jObject = JObject.FromObject(value, serializer);私はそのコンバータで構成されていたJsonSerializerの同じインスタンスを使用するので、それは明らかです。

このコンバータを使用しないようにするには、このシリアライザ用に設定された他のコンバータを使用しますか?私はシリアライズしたい

タイプ:

public interface ITaskResult { 
} 

public class UserHasRejectedOffer : ITaskResult { 
    public string Message { get; set; } 
} 

public class UserHasFilledForm : ITaskResult { 
    public string FormValue1 { get; set; } 

    public string Formvalue2 { get; set; } 
} 

... 
+0

あなたがシリアライズしようとしているタイプのコードを投稿してください。 – Aybe

答えて

2

あなたはその後、無限再帰を引き起こしコンバータを除いて、元のシリアライザからすべてのコンバータをコピー、JsonSerializerの新しいインスタンスを作成しようとしたことがありますか?

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
{ 
    JsonSerializerSettings settings = new JsonSerializerSettings 
    { 
     Converters = serializer.Converters.Where(s => !(s is TypeInfoConverter)).ToList() 
     // also copy any other custom settings from the serializer you wish to pass through 
     DateFormatHandling = serializer.DateFormatHandling, 
     MissingMemberHandling = serializer.MissingMemberHandling, 
     NullValueHandling = serializer.NullValueHandling, 
     Formatting = serializer.Formatting 
    }; 
    var localSerializer = JsonSerializer.Create(settings); 

    var jObject = JObject.FromObject(value, localSerializer); 
    jObject.AddFirst(new JProperty("Type", value.GetType().Name)); 
    jObject.WriteTo(writer); 
} 
+0

しかし、私はまだDateFormatHandling、MissingMemberHandlingなどのような他のJsonSerializerSettingsが必要です。 – Exta

+0

はい、私は上記のコードのコメントに注意しました。必要な設定を外部シリアライザから新しいシリアライザにコピーするだけです。 –

10
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    var converters = serializer.Converters.Where(x => !(x is TypeInfoConverter)).ToArray(); 

    var jObject = JObject.FromObject(value); 
    jObject.AddFirst(new JProperty("Type", value.GetType().Name)); 
    jObject.WriteTo(writer, converters); 
} 
+2

これは私より優れた解決策です。実際には、個々のプロパティを個別に記述するのではなく、本来のように 'jObject.WriteTo(writer、converters)'を実行するだけです。 –

関連する問題