Search code examples
c#jsonserializationuwpdeserialization

Serializing objects within a class to JSON producing {}


I am working on a project where I am saving information about the user to a file for later when the user reopens the application or changes sessions. A session contains information about what the user was working on and the interface state.

I wrote some methods to serialize/deserialize my "UserData" class that processes data to/from a file "user.json", however, I noticed that some objects were not being serialized.

For example, in UserData I have a List of "Sessions". While strings/ints in my UserData class are serialized as expected, objects aren't. "user.json" shows each Session object as "{}" instead of the serialized classes/variables.

My issue is similar to this, but this didn't fix it.

I would like to know how these objects can be fully serialized using methods in UserData (which handles the serialization/deserialization of itself) or if there is a better way to do this.

Here are some of the classes I am working with:

UserData class

public class UserData
{
    public List<appSession> userSessions { get; set;}
    public DatabaseConnection lastDatabaseConnection { get; set;}
    public string temp { get; set;  }

    public UserData() { userSessions = new List<appSession>();    }

    public async Task<StorageFile> Create()
    {
        StorageFolder appData = ApplicationData.Current.LocalFolder;
        StorageFile udFile = null;

        try {
            udFile = await appData.CreateFileAsync(@"UserData\user.json");
            var options = new JsonSerializerOptions { WriteIndented = true };
            string udData = JsonSerializer.Serialize(new UserData(), options);
            await Windows.Storage.FileIO.WriteTextAsync(udFile, udData);
            return udFile; }
        catch (Exception ex2) {  return null; }
    }

    public async Task<UserData> Load()
    {
        StorageFolder appData = ApplicationData.Current.LocalFolder;
        StorageFile udFile = null;
        UserData cmData;
        Helper help = new Helper();

        // Try to either load or create the VIPER user data file.
        try {
            udFile = await appData.GetFileAsync(@"UserData\user.json"); }
        catch (UnauthorizedAccessException)  {  }
        catch (FileNotFoundException){
            try { udFile = await Create(); } catch {} }

        if (udFile == null) {
            return null;
        } else {
            try {
                string udresult = await help.ReadAllTextFromFile(udFile);
                cmData = JsonSerializer.Deserialize<UserData>(udresult);
                return cmData; }
            catch (Exception ex) {
                try {
                    await udFile.RenameAsync("badUserData." + System.DateTime.Now.ToString("MM-dd-yyyy hh.mm.ss tt") + ".jsonold");
                    udFile = await appData.CreateFileAsync(@"UserData\user.json");
                    var options = new JsonSerializerOptions { WriteIndented = true };
                    string udData = JsonSerializer.Serialize(new UserData(), options);
                    await Windows.Storage.FileIO.WriteTextAsync(udFile, udData);
                    return await Load(); }
                catch (Exception ex2){
                    return null;}
            }
        }
    }

    public async void Save()
    {
        try {
            StorageFile udFile = await ApplicationData.Current.LocalFolder.GetFileAsync(@"UserData\user.json");
            var options = new JsonSerializerOptions { WriteIndented = true };
            var udData = JsonSerializer.Serialize(this, options);
            await Windows.Storage.FileIO.WriteTextAsync(udFile, udData);
        } catch(Exception ex) { }
    }
}

"user.json" file output:

{
  "userSessions": [
    {},
    {}
  ],
  "lastDatabaseConnection": null,
  "temp": "test test test"
}

appSession Class:

public class appSession
    {
        public SiteConnection LinkedSite;
        internal ImageUploaderData IUSession;

        public appSession(SiteConnection linkedSite)
        {
            LinkedSite = new SiteConnection(linkedSite);
            IUSession = new ImageUploaderData();
        }
    }

ImageUploaderData class

    internal class ImageUploaderData
    {
        List<WorkingImage> workAreaImages;

        public ImageUploaderData()
        {
            List<WorkingImage> workAreaImages = new List<WorkingImage>();
        }
    }

WorkingImage class

    internal class WorkingImage : WorkingFile
    {
        public enum TaggingState
        {
            Untagged,
            Issue,
            Tagged
        }

        string EXIF_filename;

        public WorkingImage() : base()
        { selected = false; }

        public WorkingImage(string path) : base(path)
        { selected = false; }
    } 
}

Solution

  • JsonSerializer needs public properties with get/set, not just fields, so fix all your classes you need to serialize, for example appSession class should be

    public class appSession
        {
            public SiteConnection LinkedSite {get;set;}
            public ImageUploaderData IUSession  {get;set;}
            public DocumentUploaderData DUSession  {get;set;}
    
            public appSession(SiteConnection linkedSite)
            {
                LinkedSite = new SiteConnection(linkedSite);
                IUSession = new ImageUploaderData();
                DUSession = new DocumentUploaderData();
            }
        }