63

I have list of objects of following class:

public class Catagory
{
    int catagoryId;
    string catagoryNameHindi;
    string catagoryNameEnglish;
    List<Object> subCatagories;
    public Catagory(int Id, string NameHindi, string NameEng,List<Object> l)
    {
        this.catagoryId = Id;
        this.catagoryNameHindi = NameHindi;
        this.catagoryNameEnglish = NameEng;
        this.subCatagories = l;
    }
}

  public class SubCatagory
{
    int subCatagoryId { get; set; }
    string subCatNameHindi { get; set; }
    string subCatNameEng { get; set; }

    public SubCatagory(int Id, string NameHindi, string NameEng)
    {
        this.subCatagoryId = Id;
        this.subCatNameEng = NameEng;
        this.subCatNameHindi = NameHindi;
    }
}

when I am converting this list to json string by using Newtonsoft.Json it returns array of empty objects.

  string json=JsonConvert.SerializeObject(list);

I am getting following result.

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

Please help me regarding this problem.

Vivek Mishra
  • 1,772
  • 1
  • 17
  • 37
  • 1
    Are you sure the list is not the list of the null Objects. As you have declared `Parameterzied` constructor. If you want to create empty object then you have to manually declare the `empty` constructor in class. – Mahesh Mar 12 '15 at 06:38
  • yeah there are no null objects in the list – Vivek Mishra Mar 12 '15 at 06:39
  • 2
    I was having the same problem using the Jackson library. Making the fields public solved the problem there too. – FrancisA Dec 06 '16 at 15:17
  • 1
    Not having public properties was exactly my issue as well. – Fütemire Jan 21 '20 at 23:22
  • 1
    Properties marked internal are a similar issue. See this post for ideas: https://stackoverflow.com/questions/26873755/json-serializer-object-with-internal-properties – John Dyer Sep 29 '20 at 13:59

4 Answers4

139

By default, NewtonSoft.Json will only serialize public members, so make your fields public:

public class Catagory
{
    public int catagoryId;
    public string catagoryNameHindi;
    public string catagoryNameEnglish;
    public List<Object> subCatagories;

    public Catagory(int Id, string NameHindi, string NameEng, List<Object> l)
    {
        this.catagoryId = Id;
        this.catagoryNameHindi = NameHindi;
        this.catagoryNameEnglish = NameEng;
        this.subCatagories = l;
    }
}

If for some reason you really don't want to make your fields public, you can instead decorate them with the JsonPropertyAttribute to allow them to be serialized and deserialized:

[JsonProperty]
int catagoryId;

This attribute also allows specifying other options, such as specifying the property name to use when serializing/deserializing:

[JsonProperty("categoryId")]
int Category;
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • 3
    Public members of the class Is not the best solution. Does Exist other better solution? – Ignacio Chiazzo Sep 18 '15 at 18:01
  • 14
    @IgnacioChiazzo Yes, you should be able to use the [`JsonPropertyAttribute`](http://www.newtonsoft.com/json/help/html/SerializationAttributes.htm) to indicate that a non-public field or property should be serialized: `[JsonProperty]private int categoryId;` – JLRishe Sep 18 '15 at 18:15
  • @JLRishe - You should add your comment as an answer as this is now how I do it rather than making everything public – Chris Hammond Aug 24 '16 at 07:35
  • 1
    @ChrisHammond Updated my answer. – JLRishe Sep 06 '16 at 10:32
  • pulling my hair out for an hour wondering why this didn't work for one class but did for another; overlooked that I did not declare my properties as `public`! – Adam Mar 22 '17 at 20:11
  • Someone changed from "public" -> "internal" a few properties and this became a nightmare! Thank you! Good to know... – Pablo Salcedo May 16 '19 at 19:23
  • I would say I pulled my hair out for 2 hours, my data was all set to internal as well. – Fieldfare Sep 20 '19 at 14:35
20

You could also decorate your class to serialize all members you want without having to specify [JsonProperty] for each of them.

[JsonObject(MemberSerialization.OptOut)]
public class Catagory {
    ...
}

The MemberSerialization enum allows you to specify what members you want to serialize:

  • MemberSerialization.OptOut: All public members are serialized.
  • MemberSerialization.OptIn: Only members marked with JsonPropertyAttribute or DataMemberAttribute are serialized.
  • MemberSerialization.Fields: All public and private members are serialized.
joalcego
  • 1,098
  • 12
  • 17
14

Another cause of this problem--the class I was attempting to serialize derived from a base class that had the [DataContract] attribute, but the derived class lacked this attribute. Once I added [DataContract] to the derived class and [DataMember] to all of the public properties of the derived class it began working immediately.

John M. Wright
  • 4,477
  • 1
  • 43
  • 61
Tom Regan
  • 3,580
  • 4
  • 42
  • 71
  • 2
    A similar thing seemed to happen to me, except with an inner class (outer had [DataContract], but inner did not). The same solution fixed it. – Evgeni Sergeev Mar 12 '19 at 07:58
9

A different problem in my case, It appears if you mark a class as [DataContract] then the properties to be serialized need to be marked [DataMember] and also should be Public.

In my case, I was migrating from WCF to web API , so didnt require any of DataContract or DataMember, so I removed all and it got serialised fine.

Manish Basantani
  • 16,931
  • 22
  • 71
  • 103