简体   繁体   中英

ApplicationSettingsBase is not serializing my classes as expected

I am attempting to use ApplicationSettingsBase to persist my classes. I have an example here. I also tried without using ApplicationSettingsBase and that seems to work fine. That example is further below.

Can someone give me some guidance on using ApplicationSettingsBase to persist my full class hierarchy? Thank you, thank you.

I am saving some intermediate instances in the first example to try to figure this out. I'm not planning on doing that in the final implementation. I can see here that it will save the intermediate data but not the nested one. I just don't understand.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;

// prefs is defined in Settings.settings with the name prefs, type WindowsFormsApplication1.Prefs, user scope, and no default value.

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Properties.Settings.Default.prefs = new Prefs();

            Test test = new Test();
            test.steps.Add("Step1");
            test.steps.Add("Step2");

            Properties.Settings.Default.prefs.tests.Add(test);

            test.Save();
            Properties.Settings.Default.Save();
            Properties.Settings.Default.prefs.Save();

            Environment.Exit(0);
        }
    }

    // WindowsFormsApplication1.Prefs
    public class Prefs : ApplicationSettingsBase
    {
        [UserScopedSetting]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)]
        public List<Test> tests
        {
            get { return ((List<Test>)(this["tests"])); }
            set { this["tests"] = value; }
        }

        public Prefs()
        {
            tests = new List<Test>();
        }
    }

    public class Test : ApplicationSettingsBase
    {
        [UserScopedSetting]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)]
        public string name
        {
            get { return ((string)(this["name"])); }
            set { this["name"] = value; }
        }

        [UserScopedSetting]
        [SettingsSerializeAs(SettingsSerializeAs.Xml)]
        public List<string> steps
        {
            get { return ((List<string>)(this["steps"])); }
            set { this["steps"] = value; }
        }

        public Test()
        {
            name = "NoName";
            steps = new List<string>();
        }

    }
}

user.config after run:

/*
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="WindowsFormsApplication1.Prefs" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        <section name="WindowsFormsApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
        <section name="WindowsFormsApplication1.Test" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
</configSections>
<userSettings>
    <WindowsFormsApplication1.Prefs>
        <setting name="tests" serializeAs="Xml">
            <value />
        </setting>
    </WindowsFormsApplication1.Prefs>
    <WindowsFormsApplication1.Properties.Settings>
        <setting name="prefs" serializeAs="Xml">
            <value />
        </setting>
    </WindowsFormsApplication1.Properties.Settings>
    <WindowsFormsApplication1.Test>
        <setting name="steps" serializeAs="Xml">
            <value>
                <ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    <string>Step1</string>
                    <string>Step2</string>
                </ArrayOfString>
            </value>
        </setting>
        <setting name="name" serializeAs="Xml">
            <value>
                <string>NoName</string>
            </value>
        </setting>
    </WindowsFormsApplication1.Test>
</userSettings>http://stackoverflow.com/questions/13798528/servicestack-text-does-not-serialize-my-object-as-expected
</configuration>
*/

Here is the example without trying to useApplicationSettingsBase:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Configuration;

// prefs is defined in Settings.settings with the name prefs, type WindowsFormsApplication1.Prefs, user scope, and no default value.

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            Properties.Settings.Default.prefs = new Prefs();

            Test test = new Test();
            test.steps.Add("Step1");
            test.steps.Add("Step2");

            Properties.Settings.Default.prefs.tests.Add(test);

            Properties.Settings.Default.Save();

            Environment.Exit(0);
        }
    }

    // WindowsFormsApplication1.Prefs
    public class Prefs
    {
        public List<Test> tests { get; set; }
        public Prefs()
        {
            tests = new List<Test>();
        }
    }

    public class Test
    {
        public string name { get; set; }
        public List<string> steps { get; set; }

        public Test()
        {
            name = "NoName";
            steps = new List<string>();
        }
    }
}

user.config after run:

/*
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
    <sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="WindowsFormsApplication1.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
    </sectionGroup>
</configSections>
<userSettings>
    <WindowsFormsApplication1.Properties.Settings>
        <setting name="prefs" serializeAs="Xml">
            <value>
                <Prefs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                    <tests>
                        <Test>
                            <name>NoName</name>
                            <steps>
                                <string>Step1</string>
                                <string>Step2</string>
                            </steps>
                        </Test>
                    </tests>
                </Prefs>
            </value>
        </setting>
    </WindowsFormsApplication1.Properties.Settings>
</userSettings>
</configuration>
*/

This answer pretty much nailed my question:

In particular, Properties.Settings.Default would normally return an instance of a Designer-created class named Settings . Calling Properties.Settings.Default.Save(); will save only the values in that object, not those in some other class.

If you have a separate class DeviceConfiguration that you want saved (as you seem to in the code you posted), you need to handle that explicitly. Simply having an instance of a subclass of ApplicationSettingsBase won't do it. You need to call the Save() method on that custom subclass yourself.

I did not realize that my custom structure did not have to be placed within Properties.Settings for it to get saved to the user.config file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM