Vaethin
Vaethin

Reputation: 346

C#: JSON Serialization of List<CustomClass> returns empty array?

So, I have a custom class 'User' like this:

class User
    {
        string firstname;
        string lastname;
        string proposedname;
        public User(string firstname, string lastname)
        {
            this.firstname = firstname;
            this.lastname = lastname;
            this.proposedname = $"{firstname}.{lastname}".ToLower();
        }
}

And another Class "UserCreator that has a method "GenerateList" and a method "WriteList" as well as a field which is simply a List :

public class UserCreator
    {
        internal List<User> Users;
        public UserCreator(int n = 1000)
        {
            Users = new List<User>();
            this.GenerateList(n);
        }
       public  void WriteList(string outputPath)
        {
            string json = Newtonsoft.Json.JsonConvert.SerializeObject(this.Users, Newtonsoft.Json.Formatting.Indented);
            System.IO.File.WriteAllText(outputPath, json);

        }

        void GenerateList(int amount)
        {
            List<User> result = new List<User>();
            ///...
            this.Users = result;
        }
    }

Everything works just fine until it get's to the Serialization part in WriteList(). Instead of working as Intended I get something like this:

[
  {},
  {},
  {},
  {},
  {},
  {},
  {},
  {}
]

I'm guessing it has to do with the fact that I'm using a List of a custom Class. Is that a known limitation of Newtonsoft.Json? Or maybe due to Access modifiers?

Upvotes: 3

Views: 930

Answers (3)

deadlydog
deadlydog

Reputation: 24384

I know the OP was using Newtonsoft.JSON, but I was having the same problem using the .NET 7's System.Text.Json serializer, and had all of my properties marked as public. The fix for me was to add the [JsonInclude] attribute to my List property.

So this did not work:

public class People
{
    public List<User> Users = new();
}

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set;}
}
...
var people = new People();

// populate people with users here...

var json = System.Text.Json.JsonSerializer.Serialize(people);

The json string would always just be {}.

Adding the [JsonInclude] attribute to the list like this fixed it:

public class People
{
    [JsonInclude]
    public List<User> Users = new();
}

Hopefully this helps others who stumble upon this question, but are using the System.Text.Json serializer.

Upvotes: 0

Yannick Meeus
Yannick Meeus

Reputation: 5890

How you have declared your class is completely encapsulating all of your User data.

Instead of properties, those are instance fields (or class members, if we're being picky), and by default these are private. Instead, take care of your access modifiers and at least expose a public getter for every property, like so:

public class User
{
    public string firstname { get; private set;}
    public string lastname { get; private set;}
    public string proposedname { get ; private set; }
    public User(string firstname, string lastname)
    {
        this.firstname = firstname;
        this.lastname = lastname;
        this.proposedname = $"{firstname}.{lastname}".ToLower();
    }
}

Upvotes: 6

Liju L
Liju L

Reputation: 124

by default access level is private, hence your firstName, lastName, proposedName are all private fields. You can either change this to public. Or you can also write your customcontractresolver for the jsonserialzation settings.

Upvotes: 1

Related Questions