如何使用Newtonsoft.Json将对象序列化为带有类型信息的json?

当我序列化某些类型的对象时,我希望在JSON中有一个类型名称的属性。 我写了一个转换器:

public class TypeInfoConverter : JsonConverter { private readonly IEnumerable _types; public TypeInfoConverter(IEnumerable 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; } } ... 

 var jsonSerializerSettings = new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All }; var json = JsonConvert.SerializeObject(instance, jsonSerializerSettings); 

http://james.newtonking.com/json/help/index.html?topic=html/SerializationSettings.htm

 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); } 

您是否尝试过创建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); }