System.InvalidOperationException: 'Указанный тип' CSharpLanguageTestingApp.CustomResult
Код: Выделить всё
1[T]' is not a supported derived type for the polymorphic type 'CSharpLanguageTestingApp.CustomResult
FallBackToNearestAncestor в настоящее время для меня ничего не делает
Пример класса:
Код: Выделить всё
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace CSharpLanguageTestingApp
{
public class AggregateOne
{
int iAmAggregateOne { get; set; } = 1;
}
public class AggregateTwo
{
public int iAmAggregateTwo { get; set; } = 2;
}
[JsonPolymorphic]
[JsonDerivedType(typeof(CustomResult), "CustomResult")]
[JsonDerivedType(typeof(dbCustomResult), "dbCustomResult")]
[JsonDerivedType(typeof(sbCustomResult), "sbCustomResult")]
[JsonDerivedType(typeof(apiCustomResult), "apiCustomResult")]
public class CustomResult
{
public int iAmAResult { get; set; } = 0;
}
public class dbCustomResult : CustomResult
{
public int iAmADbResult { get; set; } = 0;
}
public class sbCustomResult : CustomResult
{
public int iAmASbResult { get; set; } = 0;
}
public class apiCustomResult : CustomResult
{
public int iAmAnApiResult { get; set; } = 0;
}
public class CompositeResult
{
public string Name { get; set; } = "CompositeResult";
[JsonConverter(typeof(PolymorphicListConverter))]
public List IndividualResults { get; set; } = new();
}
}
Код: Выделить всё
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Threading.Tasks;
namespace CSharpLanguageTestingApp
{
public class PolymorphicListConverter : JsonConverter
{
public override List Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var results = new List();
// Ensure we're at the start of the array
if (reader.TokenType == JsonTokenType.StartArray)
{
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
if (reader.TokenType == JsonTokenType.StartObject)
{
using (JsonDocument doc = JsonDocument.ParseValue(ref reader))
{
JsonElement root = doc.RootElement;
if (root.TryGetProperty("$type", out JsonElement typeElement))
{
string typeName = typeElement.GetString();
Type type = Type.GetType(typeName);
if (type != null)
{
var json = root.GetProperty("Data").GetRawText();
var obj = JsonSerializer.Deserialize(json, type, options);
results.Add(obj);
}
}
}
}
}
}
return results;
}
public override void Write(Utf8JsonWriter writer, List value, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var result in value)
{
if (result != null)
{
try
{
// Get the runtime type of the object
var resultType = result.GetType();
writer.WriteStartObject();
writer.WriteString("$type", resultType.AssemblyQualifiedName);
writer.WritePropertyName("Data");
// Serialize the object as is
string json = "";
try
{
json = JsonSerializer.Serialize(result, options); // try 1
}catch (Exception ex)
{
Console.WriteLine($"Error serializing object of type {result.GetType()}: {ex.Message}");
}
try
{
JsonSerializer.Serialize(writer, result, resultType, options); // try 2
}
catch (Exception ex)
{
Console.WriteLine($"Error serializing object of type {result.GetType()}: {ex.Message}");
}
writer.WriteEndObject();
}
catch (Exception ex)
{
Console.WriteLine($"Error serializing object of type {result.GetType()}: {ex.Message}");
throw; // Rethrow or handle the exception as needed
}
}
}
writer.WriteEndArray();
}
}
}
Код: Выделить всё
CompositeResult compositeResult = new CompositeResult();
compositeResult.IndividualResults.Add(new dbCustomResult());
compositeResult.IndividualResults.Add(new CustomResult());
compositeResult.IndividualResults.Add(new sbCustomResult());
compositeResult.IndividualResults.Add(new apiCustomResult());
var options = new JsonSerializerOptions();
options.Converters.Add(new PolymorphicListConverter());
string json = "";
try
{
json = System.Text.Json.JsonSerializer.Serialize(compositeResult, options);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.WriteLine(json);
Пытался изменить конвертер, но пока безуспешно
Пока я не могу добиться, чтобы универсальные производные типы и базовые типы хорошо работали в одном списке при сериализации/десериализации
Подробнее здесь: https://stackoverflow.com/questions/791 ... -sharp-net