34

特定の型のオブジェクトをシリアル化するときに、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; }
}

...
4

3 に答える 3

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);
}
于 2013-10-15T05:43:23.217 に答える