Я пишу custom System.Text.Json.JsonConverter
, чтобы обновить старую модель данных до новой версии. Я переопределил Read()
и реализовал необходимую постобработку. Однако мне вообще не нужно делать ничего настраиваемого в _ 3_ метод. Как я могу автоматически сгенерировать сериализацию по умолчанию, которую я получил бы, если бы у меня вообще не было конвертера? Очевидно, я мог бы просто использовать разные JsonSerializerOptions
для десериализации и сериализации, однако моя структура не предоставляет напрямую разные варианты для каждого.
Ниже приводится упрощенный пример. Скажем, у меня раньше была следующая модель данных:
public record Person(string Name);
Который я обновил до
public record Person(string FirstName, string LastName);
Я написал конвертер следующим образом:
public sealed class PersonConverter : JsonConverter<Person>
{
record PersonDTO(string FirstName, string LastName, string Name); // A DTO with both the old and new properties.
public override Person Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dto = JsonSerializer.Deserialize<PersonDTO>(ref reader, options);
var oldNames = dto?.Name?.Split(' ', StringSplitOptions.RemoveEmptyEntries) ?? Enumerable.Empty<string>();
return new Person(dto.FirstName ?? oldNames.FirstOrDefault(), dto.LastName ?? oldNames.LastOrDefault());
}
public override void Write(Utf8JsonWriter writer, Person person, JsonSerializerOptions options)
=> // What do I do here? I want to preserve other options such as options.PropertyNamingPolicy, which are lost by the following call
JsonSerializer.Serialize(writer, person);
}
И туда и обратно с
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
Converters = { new PersonConverter() },
};
var person = JsonSerializer.Deserialize<Person>(json, options);
var json2 = JsonSerializer.Serialize(person, options);
Тогда результат будет {"FirstName":"FirstName","LastName":"LastName"}
- т.е. оболочка верблюда при сериализации потеряна. Но если я передаю параметры во время записи, рекурсивно вызывая
public override void Write(Utf8JsonWriter writer, Person person, JsonSerializerOptions options)
=> // What do I do here? I want to preserve other options such as options.PropertyNamingPolicy, which are lost by the following call
JsonSerializer.Serialize(writer, person, options);
Затем сериализация не выполняется из-за переполнения стека.
Как я могу получить точную сериализацию по умолчанию, которая игнорирует настраиваемый конвертер? Не существует эквивалента свойству Json.NET JsonConverter.CanWrite
в Json.NET.
Демо-скрипт здесь.