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:
I did not realize that my custom structure did not have to be placed within
Properties.Settings
for it to get saved to theuser.config
file.