Код: Выделить всё
public sealed record Descriptor(T Value, string Description);
Код: Выделить всё
[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(Descriptor))]
[JsonSerializable(typeof(Descriptor))]
public partial class DescriptorContext: JsonSerializerContext{}
< /code>
Теперь, когда у вас есть несколько типов перечисления, это не красиво. Тем не менее, кажется, что вам также нужно добавить записи, если вы хотите сериализовать коллекции каждого типа дескриптора: < /p>
[JsonSourceGenerationOptions(GenerationMode = JsonSourceGenerationMode.Serialization)]
[JsonSerializable(typeof(Descriptor))]
[JsonSerializable(typeof(IEnumerable))]
[JsonSerializable(typeof(List))]
// removed entries for KindB
public partial class DescriptorContext: JsonSerializerContext{}
List items = [
new(Kind.Single, "Single"),
new(Kind.Colective, "Colective")
];
string serialized = JsonSerializer.Serialize(items,
DescriptorContext.Default.ListDescriptorKind);
List recovered =
JsonSerializer.Deserialize(serialized,
DescriptorContext.Default.ListDescriptorKind)!;
foreach( Descriptor item in recovered ) {
Console.WriteLine($"{item.Value} {item.Description}");
}
< /code>
Это правильно? Я имею в виду, правильно ли заключить, что:
- Вы не можете указать открытый тип
- Вы должны указать все типы, которые вы хотите сериализовать/пустынь через JsonserializableAttribute , включая закрытые общины, такие как то, что показано на предыдущей Snippet (Ex. Список )
public async Task DoSomething(){
// always returns an instance of a Base's derived type
}
< /code>
Первоначально сериализация была сделана с помощью json.net. Тем не менее, мы закончили тем, что перешли на System.text.json, когда он официально поддерживает наследование. В то время мы в итоге прибегли к пользовательскому DefaultJsontypeinforesolver , чтобы используемый дискриминатор совместим с тем, что сгенерирован по умолчанию json.net (имя свойства установлено в $ type , а его значение является квалифицированным именем с полной сборкой). Это потребовалось, потому что некоторые из типов, используемых в API, также сохранялись в базе данных. Вот некоторый демонстрационный код, используемый для defaultjsontypeinforesolver :
Код: Выделить всё
public class JsonHierarchyTypeInfoResolver : DefaultJsonTypeInfoResolver {
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options) {
var jsonTypeInfo = base.GetTypeInfo(type, options);
var jsonType = jsonTypeInfo.Type;
if( jsonType == typeof(Equipamento) ) {
jsonTypeInfo = GetTypeInfoForDevice(jsonTypeInfo);
}
// ... remaining code removed
}
private static JsonTypeInfo GetTypeInfoForDevice(JsonTypeInfo jsonTypeInfo) {
jsonTypeInfo.PolymorphismOptions = new JsonPolymorphismOptions {
TypeDiscriminatorPropertyName = "$type",
IgnoreUnrecognizedTypeDiscriminators = true,
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FailSerialization
};
foreach(var jsonDerivedType in _derivedDevicesTypes) {
jsonTypeInfo.PolymorphismOptions.DerivedTypes.Add(
new JsonDerivedType(jsonDerivedType,
jsonDerivedType.AssemblyQualifiedName!));
}
return jsonTypeInfo;
}
}
< /code>
Итак, окончательные 2 вопроса: < /p>
[list]
[*] Можно ли объединить этот резоливер с тем, что сгенерировано генераторами источников? Или они работают только с полиморфными атрибутами (Ex.: Jsonderivedtypeattribute [*] Если нет, то это означает, что мне придется переписать новую сборку DTO, которая использует полиморфные атрибуты, чтобы повторно использовать API, на основе Polymorphism/inherishance (i.e. Полученные типы)?
[/list]
Подробнее здесь: https://stackoverflow.com/questions/778 ... generators
Мобильная версия