Home > Software design >  Unable to save and then load app settings via JSON - 'System.Text.Json.JsonElement' to typ
Unable to save and then load app settings via JSON - 'System.Text.Json.JsonElement' to typ

Time:05-07

Using the below code, I'm trying to save app settings data in JSON format so it's easily readable and (in theory) easy to load back directly into data structures. Unfortunately it's not working out that way.

My general strategy is to ahve a series of lists representing different types of settings which I'll drop into one ListDictionary and then save as a single JSON object. Then, in theory, I load it back to a ListDictionary and recast the values into the lists they started as.

        // Paths to pin to quick menu in Windows Explorer
        public List<string> quickPaths = new List<string>();

        public string diag = "";
        public string settingsFile = System.AppDomain.CurrentDomain.BaseDirectory   "customizer_settings.json";


        public Prefs()
        {
            ListDictionary prefs = LoadPrefs();
            quickPaths = (List<string>)prefs["quickPaths"];
        }


        public ListDictionary LoadPrefs() 
        { 
            if (!File.Exists(settingsFile)) return new ListDictionary();
            string json = File.ReadAllText(settingsFile);
            return JsonSerializer.Deserialize<ListDictionary>(json);
        }

        public void SavePrefs()
        {
            ListDictionary toSave = new ListDictionary();
            toSave["quickPaths"] = quickPaths;
            File.WriteAllText(settingsFile, JsonSerializer.Serialize(toSave));
        }

Instead, I'm getting the error in the title on the quickPaths assignment in the Prefs() constructor. I've looked it up and there's nothing else out there about this error specifically and no workarounds I've been able to find.

I've tried iterating over the prefs["quickPaths"] value and manually adding them one at a time to the List, but that's both inelegant and doesn't work anyway. Clearly I'm doing something wrong, but I don't know what. I thought I would get from deserialize exactly what I serialized, but it seems it doesn't work that way.

Here's what the output of the save function looks like:

{"quickPaths":["C:\\output","C:\\Users","C:\\Windows"]}

CodePudding user response:

Try with the Newtonsoft like this

public class Prefs
{
    public List<string> quickPaths = new List<string>();

    public string diag = "";
    public string settingsFile = System.AppDomain.CurrentDomain.BaseDirectory   "customizer_settings.json";


    public Prefs()
    {
        ListDictionary prefs = LoadPrefs();
        quickPaths =  ((JArray)prefs["quickPaths"]).ToObject<List<string>>();
      
    }


    public ListDictionary LoadPrefs()
    {
        if (!File.Exists(settingsFile)) return new ListDictionary();
        string json = File.ReadAllText(settingsFile);
        return JsonConvert.DeserializeObject<ListDictionary>(json);
    }

    public void SavePrefs()
    {
        ListDictionary toSave = new ListDictionary();
        toSave["quickPaths"] = quickPaths;
        File.WriteAllText(settingsFile, JsonConvert.SerializeObject(toSave));
    }

}

or you can deserialize one more time, like

quickPaths = JsonSerializer.Deserialize<List<string>>(((JsonElement)prefs["quickPaths"]).GetRawText()); 

CodePudding user response:

I tried the Newtonsoft method including the deserializing of the sub-element and it didn't work (at least not how I implemented it).

Instead I re-evaluated my data structures and got rid of the ListDictionary in favor of Dictionary<string,List> since that's what I was doing anyway.

From there, I just needed to convert the comma-separated string to a list which can be done with built-in functions like so:


        // Paths to pin to quick menu in Windows Explorer
        public List<string> quickPaths = new List<string>();

        public string diag = "";
        public string settingsFile = System.AppDomain.CurrentDomain.BaseDirectory   "customizer_settings.json";


        public Prefs()
        {
            Dictionary<string,List<string>> prefs;
            prefs = LoadPrefs();
            quickPaths = prefs["quickPaths"].ToList<string>();
        }


        public Dictionary<string,List<string>> LoadPrefs() 
        { 
            if (!File.Exists(settingsFile)) return new Dictionary<string,List<string>>();
            string json = File.ReadAllText(settingsFile);
            return JsonSerializer.Deserialize<Dictionary<string,List<string>>>(json);
        }

        public void SavePrefs()
        {
            Dictionary<string,List<string>> toSave = new Dictionary<string,List<string>>();
            toSave["quickPaths"] = quickPaths;
            File.WriteAllText(settingsFile, JsonSerializer.Serialize(toSave));
        }

  • Related