Можете ли вы расширить JsonConverter по умолчанию, используемый в JSON.NET для коллекций?

Я пытаюсь написать собственный JsonConverter для случаев, когда человек создает подкласс списка или коллекции, но затем добавляет в подкласс дополнительные свойства (см. здесь). Текущая реализация JSON.NET просто изменяет список на массив дочерних объектов и игнорирует все добавленные свойства. Итак, я хочу написать новый JsonConverter, который обрабатывает объект так, как если бы он не был списком, и просто сериализовал все остальное как обычно, но затем добавил в сериализацию новое свойство под названием «_Items». где хранится фактический массив данных.

Я уже написал класс, который делает именно это для нашего конкретного подкласса List, но мне пришлось вручную указывать все свойства одно за другим. Но если бы я мог написать преобразователь, который обрабатывает это как обычный объект, а затем вручную обрабатывает элементы, я был бы золотым. Меня даже не волнует, дублирую ли я половину другого класса (или даже больше!), но я хотел бы сделать многоразовый преобразователь для этих случаев. Однако, как я уже сказал, я не могу найти конвертер по умолчанию, с которого можно начать.

Итак... кто-нибудь знает, где это?


person Mark A. Donohoe    schedule 04.05.2011    source источник
comment
Не совсем то, что я искал, но это дает мне представление о том, как идти.   -  person Mark A. Donohoe    schedule 09.08.2018


Ответы (2)


В JSON.NET нет «преобразователя по умолчанию».

Если вы можете изучить JsonSerializerInternalWriter посмотрите на метод SerializeValue. В нем вверху находится этап «найти и выполнить конвертер». Однако, если нет подходящего преобразователя, он прибегает к сериализации типа контракта (оператор switch).

Я не нашел способ (правильный способ или изящный хак), чтобы иметь возможность выполнять общую сериализацию контракта (например, анализ объекта в обычном режиме) с расширенной пользовательской сериализацией объекта (которую, как я предполагаю, вы пытаетесь делать).

person jdknight    schedule 11.09.2013

Как сказал здесь @dbc, вы можете переопределить CanRead и CanWrite, чтобы вернуть false и зарегистрировать CustomAsDefaultConvertor : JsonConverter для своей собственности.

Мое дело:

public class AsDefaultConverter : JsonConverter<JObject>
{
    public override JObject ReadJson(JsonReader reader, Type objectType, JObject existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, JObject value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanWrite => false;

    public override bool CanRead => false;
}

МояМодель:

public class MyModel
{
    /// <summary>
    /// Gets or sets event id
    /// </summary>
    public string EventId { get; set; }

    /// <summary>
    /// Gets or sets trigger name
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Gets or sets arguments
    /// </summary>
    [JsonConverter(typeof(AsDefaultConverter))]
    public JObject Arguments { get; set; }

    /// <summary>
    /// Gets or sets trigger creation date
    /// </summary>
    public DateTimeOffset Created { get; set; }

    /// <summary>
    /// Gets or sets trigger creator
    /// </summary>
    public User CreatedBy { get; set; }
} 

При регистрации startUp я переопределил дефолтную JsonSerialization на свою кастомную, но для свойства JObject Arguments указал преобразователь, который мне нужен в данном случае.

person Yaroslav    schedule 17.08.2019