Configuration.Save Writes Invalid Configuration File
-
I am using VS 2019, .Net 4.5.2 on Windows 7. I have an application which manages a configuration file for another application. The abridged version looks like:
When I run the program to modify the configuration file to add a new group with code such as:
namespace My
{
public class StepGroups : ConfigurationSectionGroup
{
public My.StepGroup AddNewGroup()
{
My.StepGroup newGroup = new My.StepGroup();
SectionGroups.Add("MyGroup2", newGroup);
}
}
}and then save the configuration file I get
As can be seen, the new
MyGroup2
declaration element gets wrapped in a newServiceConfiguration/ServiceStepGroups
construct but 1) AFTER the first construct, 2) WITHOUT type attributes and 3) WITHOUT aCustomSection
section; however, theMyGroup2
configuration group IS in the right place in the configuration file below. Why? I -
I am using VS 2019, .Net 4.5.2 on Windows 7. I have an application which manages a configuration file for another application. The abridged version looks like:
When I run the program to modify the configuration file to add a new group with code such as:
namespace My
{
public class StepGroups : ConfigurationSectionGroup
{
public My.StepGroup AddNewGroup()
{
My.StepGroup newGroup = new My.StepGroup();
SectionGroups.Add("MyGroup2", newGroup);
}
}
}and then save the configuration file I get
As can be seen, the new
MyGroup2
declaration element gets wrapped in a newServiceConfiguration/ServiceStepGroups
construct but 1) AFTER the first construct, 2) WITHOUT type attributes and 3) WITHOUT aCustomSection
section; however, theMyGroup2
configuration group IS in the right place in the configuration file below. Why? II've never had to save anything from code in the config file, but it would seem that you would want to get the object for the ServiceConfiguration sectionGroup first, add your sectionGroup to that, then resave.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave Kreskowiak -
I've never had to save anything from code in the config file, but it would seem that you would want to get the object for the ServiceConfiguration sectionGroup first, add your sectionGroup to that, then resave.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave KreskowiakHi Dave, Thanks for responding. Yes, you are correct. Perhaps I was too brief in my code snippet. But I am able to go in with the debugger and everything appears as it should be; the right sections and groups have the right children, etc. I have written configuration files before but I can't recall if I was attempting to write multiple groups (different names but same type) as I am now. But again, when I make changes manually and read the file back in everything works, which tells me that the internal mechanisms can handle multiple groups (different names but same type) just fine. Hence the perplexing puzzle.
-
I am using VS 2019, .Net 4.5.2 on Windows 7. I have an application which manages a configuration file for another application. The abridged version looks like:
When I run the program to modify the configuration file to add a new group with code such as:
namespace My
{
public class StepGroups : ConfigurationSectionGroup
{
public My.StepGroup AddNewGroup()
{
My.StepGroup newGroup = new My.StepGroup();
SectionGroups.Add("MyGroup2", newGroup);
}
}
}and then save the configuration file I get
As can be seen, the new
MyGroup2
declaration element gets wrapped in a newServiceConfiguration/ServiceStepGroups
construct but 1) AFTER the first construct, 2) WITHOUT type attributes and 3) WITHOUT aCustomSection
section; however, theMyGroup2
configuration group IS in the right place in the configuration file below. Why? IAfter laborious effort I was able to understand what was happening. Generally, I would consider the behavior in the OP as a bug with the .NET code since it can't read in what it writes out; however, the code seems structured and designed to produce this behavior; therefore, the behavior doesn't appear to be a mistake, just a sore and undocumented design with unintuitive behavior. Since this is such odd, undocumented and unintuitive behavior I felt compelled to share my findings with posterity. Here is what I found: Public APIs:
System.Configuration.ConfigurationSectionGroup
This is the configuration construct used to group sections and other groups, essentially a container. It can be subclassed but itself derives from nothing and offers little functionality so it offers little opportunity for customization.System.Configuration.Configuration
Similar toConfigurationSectionGroup
in that it essentially acts as a container for sections and groups and derives from nothing; however, it is sealed and cannot be subclassed. It provides contextual information, some fundamental constructs for processing connection strings and application settings and the API for saving the configuration to file. It provides some flexibility for customization via delegate actions. So, by and large, most of the processing of configuration files is behind the scenes and internal to the .NET framework. Therefore, to study these mechanisms required looking into the .NET code base and decompiling the necessary code in the VS debugger. System.Configuration.MgmtConfigurationRecordSystem.Configuration.BaseConfigurationRecord
These classes are internal to the .NET framework and provide much of the guts of configuration management. Simply, each configuration [file] is associated with one configuration record. The configuration record provides bookkeeping of what is in the configuration file and how the configuration information is written.SaveAs(string filename, ConfigurationSaveMode saveMode, bool forceUpdateAll)
This method is called whenever a user wants to save the configuration file. It manages the save process, essentially providing a wrapper around save functionality and providing error handling. It callsCopyConfig(...)
whose job it is to copy -
After laborious effort I was able to understand what was happening. Generally, I would consider the behavior in the OP as a bug with the .NET code since it can't read in what it writes out; however, the code seems structured and designed to produce this behavior; therefore, the behavior doesn't appear to be a mistake, just a sore and undocumented design with unintuitive behavior. Since this is such odd, undocumented and unintuitive behavior I felt compelled to share my findings with posterity. Here is what I found: Public APIs:
System.Configuration.ConfigurationSectionGroup
This is the configuration construct used to group sections and other groups, essentially a container. It can be subclassed but itself derives from nothing and offers little functionality so it offers little opportunity for customization.System.Configuration.Configuration
Similar toConfigurationSectionGroup
in that it essentially acts as a container for sections and groups and derives from nothing; however, it is sealed and cannot be subclassed. It provides contextual information, some fundamental constructs for processing connection strings and application settings and the API for saving the configuration to file. It provides some flexibility for customization via delegate actions. So, by and large, most of the processing of configuration files is behind the scenes and internal to the .NET framework. Therefore, to study these mechanisms required looking into the .NET code base and decompiling the necessary code in the VS debugger. System.Configuration.MgmtConfigurationRecordSystem.Configuration.BaseConfigurationRecord
These classes are internal to the .NET framework and provide much of the guts of configuration management. Simply, each configuration [file] is associated with one configuration record. The configuration record provides bookkeeping of what is in the configuration file and how the configuration information is written.SaveAs(string filename, ConfigurationSaveMode saveMode, bool forceUpdateAll)
This method is called whenever a user wants to save the configuration file. It manages the save process, essentially providing a wrapper around save functionality and providing error handling. It callsCopyConfig(...)
whose job it is to copyThis is definitely worth writing up as a Tip/Trick! That will make the results of your spelunking more permanently visible and searchable. Forum messages like this are, by their very nature, transient. Cheers, Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
-
This is definitely worth writing up as a Tip/Trick! That will make the results of your spelunking more permanently visible and searchable. Forum messages like this are, by their very nature, transient. Cheers, Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
Thanks for the feedback. How do I do this? Or is that a forum SysAdmin prerogative?
-
Thanks for the feedback. How do I do this? Or is that a forum SysAdmin prerogative?
-
Thanks for the feedback. How do I do this? Or is that a forum SysAdmin prerogative?
Member 12660776 wrote:
How do I do this?
You could start here: Submit a new Article[^] :) And no, you do not need admin prerogatives to submit an article/tip/trick/reference. Yours would make a nice tip/trick, indeed. The process of finding the cause is at least as important as the actual resolution, imho.
"Five fruits and vegetables a day? What a joke! Personally, after the third watermelon, I'm full."
-
I've never had to save anything from code in the config file, but it would seem that you would want to get the object for the ServiceConfiguration sectionGroup first, add your sectionGroup to that, then resave.
Asking questions is a skill CodeProject Forum Guidelines Google: C# How to debug code Seriously, go read these articles.
Dave KreskowiakThanks for sharing with us!