Hank Hank - 3 months ago 16
C# Question

Loading user settings from XML with settings.Object not set to an instance of object

My WinForm program saves out an xml copy of user settings, the problem I'm having is loading it back in again.

I have copied this code from a blog: Code Snippet

The error occuring happens where commented in the code below.


Could not import settings. Object reference not set to an instance of
an object.


[Update] I have just noticed that it actually works when running the program from Visual Studio 2013, however does not when run from Windows File Explorer.

[Update2] I think because it is the first time I had run this from the desktop, I'm a different user and my user settings config file has not been created yet, this is the issue.

try{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);

// returns "[MyApplication].Properties.Settings";
string appSettingsXmlName = Properties.Settings.Default.Context["GroupName"].ToString();
// Open settings file as XML
var import = XDocument.Load(filename);
// Get the whole XML inside the settings node
var settings = import.XPathSelectElements("//" + appSettingsXmlName);

//***Error occurs in the following code***
config.GetSectionGroup("userSettings")
.Sections[appSettingsXmlName]
.SectionInformation
.SetRawXml(settings.Single().ToString());

config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("userSettings");

appSettings.Reload();
}
catch (Exception ex)
{
MessageBox.Show("Could not import settings. " + ex.Message);
}


Here is the XML file:

<?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="DropLib.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<DropLib.Properties.Settings>
<setting name="ORG_SETTINGS" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<string>ORG1-||-server1-||-Proj 94-||-email@ORG1.com-|||-Server-|-Server-|-Folder$-|-http://server1/proj-|-c:\inetpub\wwwroot\proj\</string>
<string>ORG2-||-server2-||-Proj 94-||-email@ORG2.com-|||-Server-|-Server-|-Folder$-|-http://server2/proj-|-c:\inetpub\wwwroot\proj\</string>
</ArrayOfString>
</value>
</setting>
</DropLib.Properties.Settings>
</userSettings>
</configuration>

Answer

It seems that you are a different user depending if you run from VS or from the desktop.

When I ran the program from the desktop for the first time, a user.config file had not been created yet.

Solution: Added a check to see if the user.config had been created, if not perform a save of the user settings, which will create it.

New Code:

try
{
    var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
    //Check user.config exists
    if (!File.Exists(config.FilePath))
    {
        [EDIT]
        DropLib.Properties.Settings.Default.MY_SETTING = "";
        [/EDIT]
        DropLib.Properties.Settings.Default.Save();
        config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
    }

    // returns "[MyApplication].Properties.Settings";
    string appSettingsXmlName = Properties.Settings.Default.Context["GroupName"].ToString();

    // Open settings file as XML
    var import = XDocument.Load(filename);

    // Get the whole XML inside the settings node
    var settings = import.XPathSelectElements("//" + appSettingsXmlName);

    config.GetSectionGroup("userSettings")
        .Sections[appSettingsXmlName]
        .SectionInformation
        .SetRawXml(settings.Single().ToString());

    config.Save(ConfigurationSaveMode.Modified);
    ConfigurationManager.RefreshSection("userSettings");

    appSettings.Reload();
}
catch (Exception ex)
{
    MessageBox.Show("Could not import settings. " + ex.Message);
    appSettings.Reload(); // from last set saved, not defaults
}