Как сериализовать объект для 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; }
}
...
Ответы
Ответ 1
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
Ответ 2
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);
}
Ответ 3
Пробовали ли вы создать новый экземпляр 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);
}