Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does an inherited class not get JSON serialized correctly?

I want to create a JsonSerializable class, that I can inherit from. See this code:

using System;
using System.Text.Json;
using System.Text.Json.Serialization;   

public interface IJson
{
    string ToJson();
}

abstract public class JsonSerializable : IJson
{
    public string ToJson()
    {
       return JsonSerializer.Serialize(this);
    }
}

public class Cabinet :JsonSerializable {
    [JsonPropertyName("name")]
    public string Name { get; set; }        
}

I use it as follows:

public class Program
{
    public static void Main()
    {
        var C = new Cabinet();
        C.Name = "FOO";

        IJson json_thing = C;
        
        Console.WriteLine(JsonSerializer.Serialize(C));
        Console.WriteLine(json_thing.ToJson());
    }
}

However, the result is:

{"name":"FOO"}
{}

Where I'd think json_thing.ToJson() should also result in {"name":"FOO"}.

Why is the JSON serialization with that extra in between class not working? I want that class in between, because the serialization code for most class will be identical.

like image 301
Bart Friederichs Avatar asked Dec 21 '25 06:12

Bart Friederichs


2 Answers

You need to take the JsonSerializer.Serialize overload that takes in the type. Otherwise you are using the generic version where the compile time type is inferred, i.e. JsonSerializable and not the derived classes:

abstract public class JsonSerializable : IJson {
    public string ToJson() {
        return JsonSerializer.Serialize(this, this.GetType());
    }
}
like image 195
Ivan Petrov Avatar answered Dec 23 '25 20:12

Ivan Petrov


Because of the difference in the declared type of the argument,

  • The working version calls: JsonSerializer.Serialize<Cabinet>(...)
  • The non-working version calls: JsonSerializer.Serialize<JsonSerializable>(...)

You can resolve the issue by replacing

return JsonSerializer.Serialize(this);

with

return JsonSerializer.Serialize(this, this.GetType());
like image 32
ikegami Avatar answered Dec 23 '25 19:12

ikegami