C# JsonSerializer.Serialize returns an empty object
Asked Answered
A

2

6

I have faced an issue about serializing struct to JSON. So, I have a struct "Coordinates"

namespace CoordinatesNameSpace
{
    public struct Coordinates
    {
        public Coordinates(string key, string x, string y, string z)
        {
            this.key = key;
            this.x = x;
            this.y = y;
            this.z = z;
        }
        public string key;
        public string x;
        public string y;
        public string z;
        public override string ToString()
        {
            return $"{key} {this.x} {this.y} {this.z}";
        }
    }
}

All properties are publics, so I expected that json serializer will return me { "key": "v", "x": "0.12331212" ... }, but it returns just an empty object.

using CoordinatesNameSpace;

namespace ObjToJSON
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Coordinates> parsedCoordinatesList = new List<Coordinates>();
            Coordinates _c;
            _c.key = splitted[0]; // "v"
            _c.x = splitted[1]; // "1.324394"
            _c.y = splitted[2]; // "-0.219625"
            _c.z = splitted[3]; // "-0.422554"
            parsedCoordinatesList.Add(_c);

            // returns an [{}, {}, {} ...]
            //string json = JsonSerializer.Serialize<List<Coordinates>>(parsedCoordinatesList);

            // returns {}
            string json = JsonSerializer.Serialize<Coordinates>(parsedCoordinatesList[0]);

Can somebody explain it to me, please – why it does so and how to make it serialize properly?

Auditory answered 3/7, 2020 at 14:54 Comment(0)
M
9

It seems that currently System.Text.Json does not support serializing fields. Change fields to properties and everything should work:

public struct Coordinates
{
    public Coordinates(string key, string x, string y, string z)
    {
        this.key = key;
        this.x = x;
        this.y = y;
        this.z = z;
    }
    public string key  { get; set; }
    public string x  { get; set; }
    public string y  { get; set; }
    public string z  { get; set; }
    public override string ToString()
    {
        return $"{key} {this.x} {this.y} {this.z}";
    }
}

Also from docs:

Serialization behavior:

...

  • Currently, fields are excluded.

UPD

Since .NET 5 fields can be included either via JsonSerializerOptions.IncludeFields global setting or via the JsonIncludeAttribute.

public struct Coordinates
{
    public Coordinates(string key, string x, string y, string z)
    {
        this.key = key;
        this.x = x;
        this.y = y;
        this.z = z;
    }
    [JsonInclude]
    public string key;
    [JsonInclude]
    public string x;
    [JsonInclude]
    public string y;
    [JsonInclude]
    public string z;

    public override string ToString()
    {
        return $"{key} {this.x} {this.y} {this.z}";
    }
}
Maeve answered 3/7, 2020 at 15:8 Comment(0)
U
1

JsonSerializer is a pretty new library introduced recently by Microsoft. It does lack few features like serialization of fields.

One option is to convert the fields to properties, which is a good suggestion because having public fields is not a good design practice as you are exposing the internal state of the object. However if that is something which cannot be avoided, then go for a sophisticated JsonSerializer like Newtonsoft.Json which is available as a Nuget package.

Newtonsoft.Json

And it can be used as shown:

string json = JsonConvert.SerializeObject(parsedCoordinatesList[0], Formatting.Indented);
Unknot answered 3/7, 2020 at 15:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.