2

I'm using the json deserialiser by newtonsoft, and I am deserialising this object inside a wrapper:

public class User
{
    public string Username;
    public byte[] HashedPassword;
    public byte[] Salt;
    private bool admin;
    public bool Admin 
    {
        get { return admin; }
    }

    public User(string UsernameArg, byte[] PasswordArg, byte[] SaltArg, bool AdminArg = false)
    {
        Username = UsernameArg;
        HashedPassword = PasswordArg;
        Salt = SaltArg;
        admin = AdminArg;
    }

    public override string ToString()
    {
        return Username;
    }
}

This is my json string:

{"Users":[{"Username":"admin","HashedPassword":"password","Salt":"salt","Admin":true}]}

(I've edited the hashed password and the salt for readability)

So whenever I read this using JsonConvert.DeserializeObject<UserDatabaseClass>(jsonRead) the admin field is returning false.

Is it just that I have misunderstood what this is doing here or am I doing it incorrectly?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Cjen1
  • 1,826
  • 3
  • 17
  • 47
  • You have to have a public getter *and* setter for all properties you wish to round-trip. With just a public getter, they'll be serialized, but without a setter, they can't be written back to the object instance during deserialization. – Joshua Shearer Dec 14 '15 at 20:29

1 Answers1

8

Since your Admin property is read-only - {get {...}} - serializer can't set it to any value and will skip it.

Fix: make field read-write, i.e. using automatic properties

public bool Admin {get;set;}

Also you may need no-argument constructor for deserialization to work or use [JsonConstructor] attribute as shown in JSON.net: how to deserialize without using the default constructor?

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • So the json serialiser only works on public properties, because I am using the private `admin` property, because I wanted the public admin property to be unable to be set – Cjen1 Dec 14 '15 at 20:33
  • 1
    @Cjen1 Yes, by default you have to have a public getter and setter for all properties to round-trip them. [There are ways around this, of course.](https://stackoverflow.com/questions/4179093/can-json-net-populate-readonly-fields-in-a-class) – Joshua Shearer Dec 14 '15 at 20:37
  • @Cjen1 by default - yes, only public properties/fields and only default constructor. You can force serialization of private fields/properties as show in http://stackoverflow.com/questions/24106986/json-net-force-serialization-of-all-private-fields-and-all-fields-in-sub-classe, but that would be very unusual - make sure to provide good explanation inline in your code if serializing private fields (so later you/someone else can understand what is going on) – Alexei Levenkov Dec 14 '15 at 20:37
  • I was struggling with this same issue, and forgot I set my fields to read-only a while ago. – Tyler Montney Dec 09 '16 at 00:57