我正在编写一个自定义的
以下是一个简化的示例。 假设我以前有以下数据模型:
System.Text.Json.JsonConverter<T>
,用于将旧数据模型升级到新版本。 我已经重写了Read()
并实现了必要的后处理。 然而,在Write()
方法中,我不需要进行任何自定义操作。 我怎样才能自动生成默认序列化,就好像我没有使用转换器一样? 显然,我可以只为反序列化和序列化使用不同的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
属性。
演示fiddle 在此处。
DefaultConverter
的构造函数中缓存了JsonConverter<T> defaultConverter
,但我已经将其删除,因为它会导致声明为object
的值的多态序列化、对NumberHandling
的支持以及编译时代码生成的问题,这些问题在这里报告。 - dbcJsonSerializerOptions.Converters
中。相反,它会被缓存在元数据信息JsonSerializerOptions._classes
中。你可以在这个 traceback 中看到它: https://dotnetfiddle.net/hy94kw... - dbcConverters
集合中由工厂生成的转换器。因此,在这种情况下,仅按照您的第二点建议删除转换器是不够的。 - Pharaz Fadaeioptions.CopyAndRemoveConverter(factory.GetType())
。然后,我将修改后的选项传递到递归序列化调用中。无论如何,如果有什么问题并且您可以通过[fiddle]提供一个最小可重现示例,我很乐意查看。 - dbc