0

I'm doing a little application where to upload a json file and deserialize its content into objects. My problem is that I have an abstract class. I made a JsonConverter but I don't know how should I call it to make a correct deserialization.

My JsonConverter code:

public class ChartJsonConverter : System.Text.Json.Serialization.JsonConverter<ChartDTO>
{
    public override ChartDTO Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        Utf8JsonReader readerClone = reader;
        using (var jsonDocument = JsonDocument.ParseValue(ref readerClone))
        {
            if (!jsonDocument.RootElement.GetPropertyCaseInsensitive("Type", out var typeProperty))
            {
                throw new JsonException();
            }

            switch (typeProperty.GetInt32())
            {
                case 2:
                case 1:
                    return JsonSerializer.Deserialize<TrendDTO>(ref reader, options);
                case 7:
                    return JsonSerializer.Deserialize<ScatterDTO>(ref reader, options);
            }
        }

        return null;
    }

    public override void Write(Utf8JsonWriter writer, GraficaDTO value, JsonSerializerOptions options)
    {

    }
}
public static class JEelementExtensions
{
    public static bool GetPropertyCaseInsensitive(this JsonElement element, string propertyName, out JsonElement value)
    {
        foreach (var property in element.EnumerateObject().OfType<JsonProperty>())
        {
            if (property.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase))
            {
                value = property.Value;
                return true;
            }
            else if (property.Name.Equals("@type", StringComparison.OrdinalIgnoreCase))
            {
                value = property.Value;
                return true;
            }
        }
        value = new JsonElement();
        return false;
    }
}

App code:

private OpenFileDialog ofd;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        ofd = new OpenFileDialog();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ofd.ShowDialog();
        if (File.Exists(ofd.FileName))
        {
            using (StreamReader reader = new StreamReader(ofd.FileName))
            {
                var text = reader.ReadToEnd();
                
                var objList = JsonConvert.DeserializeObject<List<ChartDTO>>(text);
                
                //More Code
               
            }
   
        }
    }

Model

[JsonConverter(typeof(ChartJsonConverter))]
public abstract class ChartDTO
{
    public int ID { get; set; }
    public int Type { get; set; }
    public int Title { get; set; }
}

public class TrendDTO : ChartDTO
{
    public int Grid { get; set; }
    public bool Axes { get; set; }
}

public class ScatterDTO : ChartDTO
{
    public int Line { get; set; }
    public int Point { get; set; }
}

With this code, it crash when I try to deserialize the objects because of the abstract ChartDTO. I assume there should be something like var options = new JsonSerializerOptions(); options.Converters.Add(new ChartJsonConverter()); but then I don't know where to add that "options".

Thank you in advance.

Weenhallo
  • 324
  • 2
  • 8
  • 2
    Is this of any relevance? https://stackoverflow.com/questions/20995865/deserializing-json-to-abstract-class – Matthew Watson Aug 03 '22 at 07:58
  • 1
    Thank you! Yes, It helped me. Also, I noticed that I always have problems working with Json because I mix System.Text.Json and using Newtonsoft.Json.... I finally made it work with this line from System.Text.Json: var objList = JsonSerializer.Deserialize>(text, options); – Weenhallo Aug 03 '22 at 08:01
  • This post seems to be related as well https://stackoverflow.com/questions/58074304/is-polymorphic-deserialization-possible-in-system-text-json/59744873#59744873 – Oleksii Rebrov Aug 03 '22 at 08:02
  • Why are you deserialising to `ChartDTO` and not to `TrendDTO` or `ScatterDTO`? – tymtam Aug 03 '22 at 08:19

0 Answers0