2014-12-02 4 views
4

Я хотел бы ввести некоторые свойства метаданных в вывод json для экземпляров определенного типа, когда JSON.NET сериализует тип.Json.NET Сериализация с дополнительными свойствами; Сохранение настроек Serializer

Каков наилучший способ введения этих дополнительных свойств при сохранении контекста и настроек сериализации?


Я знаю, что я могу реализовать JsonConverter и добавить его в настройках Serializer. Вот пример реализации WriteJson:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
{ 
    var Json = JObject.FromObject(value, serializer); 

    //modify Json by adding some properties ... 

    Json.WriteTo(writer); 
} 

Однако это вызывает некоторые проблемы, которые я не знаю, как обойти:

Если сериализатору настраивается путем установки:

ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore

затем пытается позвонить JObject.FromObject(value, serializer) ничего не сериализует, так как JSON.NET уже определил, что значение сериализуется (и поэтому он игнорирует дальнейшие попытки сериализации того же r правочник).

Если я установил ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize, тогда я получаю бесконечный цикл рекурсии. Вызов JObject.FromObject(value, serializer) заканчивается повторным вводом WriteJson моих обычаев JsonConverter.

Если вместо этого я создаю новый сериализатор или звоню JObject.FromObject(value) (как показано в this example), я больше не буду использовать одни и те же настройки сериализатора. Хотя выход будет иметь дополнительные свойства, он может не соответствовать остальной части сериализованного json, если для исходного сериализатора были настроены другие преобразователи, преобразователи контрактов и т. Д. Кроме того, я потерял контекст сериализации для обработки опорного контура, и поэтому ссылки, которые были бы пропущены в первоначальном выходе больше не будут пропущены.

Есть ли лучший способ подключиться к процессу сериализации, который позволяет вам модифицировать json, созданный исходным сериализатором?


Обновление: Сейчас я реализовал менее, чем хотелось бы обходной путь, который должен обеспечить настройки завода Func<JsonSerializerSettings> к моему обычаю JsonConverter. Предоставляемые параметры должны исключать конвертер, чтобы избежать цикла рекурсии, и это не сохраняет контекст сериализации. Кроме того, любые вложенные объекты не получат дополнительных свойств, поскольку преобразователь больше не настроен.

ответ

5

Я понял, что могу реализовать пользовательский IContractResolver и переопределить CreateProperties, чтобы включить любое количество дополнительных свойств вместе с IValueProvider, которое содержит фактические значения свойств.

Вместо того чтобы писать JsonConverter для сериализации объекта, а затем добавить свойства, этот подход изменяет контракт для определенного типа, который затем используется сериализатором.

protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) 
{ 
    var Result = base.CreateProperties(type, memberSerialization); 

    //check if this is a type we add properties to 
    if (IsAnnotatedType(type)) 
    { 
     Result.Add(new JsonProperty 
     { 
      PropertyType = typeof(string), 
      PropertyName = "AdditionalProperty", 
      Readable = true, 
      Writable = false, 

      //value provider will receive the object instance when GetValue is called 
      ValueProvider = new AdditionalPropertyValueProvider() 
     }); 
    } 

    return Result; 
} 
Смежные вопросы