none
How to write App.Config RRS feed

  • Question

  • This code is just copied from MSDN, which is the sample code of Configuration Class.

    // Define a custom section.
        // The CustomSection type allows to define a custom section 
        // programmatically.
        public sealed class CustomSection :
            ConfigurationSection
        {
            // The collection (property bag) that contains 
            // the section properties.
            private static ConfigurationPropertyCollection _Properties;
    
            // Internal flag to disable 
            // property setting.
            private static bool _ReadOnly;
    
            // The FileName property.
            private static readonly ConfigurationProperty _FileName =
                new ConfigurationProperty("fileName",
                typeof(string), "default.txt",
                ConfigurationPropertyOptions.IsRequired);
    
            // The MaxUsers property.
            private static readonly ConfigurationProperty _MaxUsers =
                new ConfigurationProperty("maxUsers",
                typeof(long), (long)1000,
                ConfigurationPropertyOptions.None);
    
            // The MaxIdleTime property.
            private static readonly ConfigurationProperty _MaxIdleTime =
                new ConfigurationProperty("maxIdleTime",
                typeof(TimeSpan), TimeSpan.FromMinutes(5),
                ConfigurationPropertyOptions.IsRequired);
    
            // CustomSection constructor.
            public CustomSection()
            {
                // Property initialization
                _Properties =
                    new ConfigurationPropertyCollection();
    
                _Properties.Add(_FileName);
                _Properties.Add(_MaxUsers);
                _Properties.Add(_MaxIdleTime);
            }
    
    
            // This is a key customization. 
            // It returns the initialized property bag.
            protected override ConfigurationPropertyCollection Properties
            {
                get
                {
                    return _Properties;
                }
            }
    
    
            private new bool IsReadOnly
            {
                get
                {
                    return _ReadOnly;
                }
            }
    
            // Use this to disable property setting.
            private void ThrowIfReadOnly(string propertyName)
            {
                if (IsReadOnly)
                    throw new ConfigurationErrorsException(
                        "The property " + propertyName + " is read only.");
            }
    
    
            // Customizes the use of CustomSection
            // by setting _ReadOnly to false.
            // Remember you must use it along with ThrowIfReadOnly.
            protected override object GetRuntimeObject()
            {
                // To enable property setting just assign true to
                // the following flag.
                _ReadOnly = true;
                return base.GetRuntimeObject();
            }
    
    
            [StringValidator(InvalidCharacters = " ~!@#$%^&*()[]{}/;'\"|\\",
                MinLength = 1, MaxLength = 60)]
            public string FileName
            {
                get
                {
                    return (string)this["fileName"];
                }
                set
                {
                    // With this you disable the setting.
                    // Remember that the _ReadOnly flag must
                    // be set to true in the GetRuntimeObject.
                    ThrowIfReadOnly("FileName");
                    this["fileName"] = value;
                }
            }
    
            [LongValidator(MinValue = 1, MaxValue = 1000000,
                ExcludeRange = false)]
            public long MaxUsers
            {
                get
                {
                    return (long)this["maxUsers"];
                }
                set
                {
                    this["maxUsers"] = value;
                }
            }
    
            [TimeSpanValidator(MinValueString = "0:0:30",
                MaxValueString = "5:00:0",
                ExcludeRange = false)]
            public TimeSpan MaxIdleTime
            {
                get
                {
                    return (TimeSpan)this["maxIdleTime"];
                }
                set
                {
                    this["maxIdleTime"] = value;
                }
            }
    
    
        }

    I want to write this to make App.Config.

    1. How to write to App.Config?

    2. How to write to other name(for example MyApp.Config)?

    Wednesday, October 3, 2018 1:19 AM

Answers

  • I think you misunderstand the purpose of the code you wrote. It is designed to allow you to define your own custom sections in an existing configuration, not create a new config file. When the config subsystem reads the config file it has to be able to map each section (at the point the section is read) to a type that can understand it. If it doesn't find one then you get a runtime error. When you start needing data outside the normal appsettings and connection strings then a custom section makes sense. That is when you write your own section handler. (Note your code is doing way too much, section handlers are generally very small).

    In order to actually use your section though you need to tell the config subsystem about it. That is what the <configSections> element is for. Ultimately a section handler isn't tied to a specific section in the code but in the config file. The runtime reads the configSections section to map sections in the config to the corresponding section handler.

    I wrote up a blog article years ago on how to create your own section handlers and use them. You might be interested in reading it.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Jeff0803 Wednesday, October 3, 2018 3:22 PM
    Wednesday, October 3, 2018 2:15 PM
    Moderator
  • To generate a config entry for your app you add a new item of type Application Configuration File. This will generate the app.config file into your code. DO NOT rename this file. At build time the compiler will rename the file to <app>.exe.config and place it into your output directory automatically.

    To actually use your custom configuration section you'll need to add an entry to the <configurationSections> element of your config. The article I linked to shows how to do this. Then you'll actually add the configuration section to your config file.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Jeff0803 Wednesday, October 3, 2018 5:08 PM
    Wednesday, October 3, 2018 4:00 PM
    Moderator

All replies

  • Hello Jeff0803,

    1. >> How to write to App.Config?

    To add a configuration file to your application, do the following :

    1.1. In the Visual Studio Project Menu, select "Add New Item".

    1.2. In the "Add New Item" dialog box that will appear, select "Application Configuration File".

    1.3. The default name will be App.Config.

    1.4. However the resultant config file that the application will access will be <application_name>.exe.config.

    1.5 My advise is that you do not change the default name to MyApp.Config. Doing so may result in <application_name>.exe.config not being automatically generated.

    2. Note that the CustomSection class pertains to a configuration file like the following :

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="CustomSection" type="ConsoleTest.CustomSection, ConsoleTest" />
      </configSections>
    
      <CustomSection fileName="default.txt" maxUsers="20" maxIdleTime="5">
      </CustomSection>
    </configuration>

    fileName, maxUsers, and maxIdleTime are attributes of CustomSection. Not elements.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Wednesday, October 3, 2018 6:51 AM
  • Hello Bio,

    I added Application Configuration file in the Visual Studio and App.Config is created in the folder where source file exists.

    My additional question is,

    1. The original App.Config is like following.

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
    </configuration>

        How could I make it to the one which CustomSection is applied?

    2. I can't find <application_name>.exe.config in the project folder.

        Where can I find it?

    Wednesday, October 3, 2018 1:17 PM
  • I think you misunderstand the purpose of the code you wrote. It is designed to allow you to define your own custom sections in an existing configuration, not create a new config file. When the config subsystem reads the config file it has to be able to map each section (at the point the section is read) to a type that can understand it. If it doesn't find one then you get a runtime error. When you start needing data outside the normal appsettings and connection strings then a custom section makes sense. That is when you write your own section handler. (Note your code is doing way too much, section handlers are generally very small).

    In order to actually use your section though you need to tell the config subsystem about it. That is what the <configSections> element is for. Ultimately a section handler isn't tied to a specific section in the code but in the config file. The runtime reads the configSections section to map sections in the config to the corresponding section handler.

    I wrote up a blog article years ago on how to create your own section handlers and use them. You might be interested in reading it.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Jeff0803 Wednesday, October 3, 2018 3:22 PM
    Wednesday, October 3, 2018 2:15 PM
    Moderator
  • Thanks for kind answer.

    May I ask a question in other words?

    I'm testing sample code MSDN provides in here.

    I compiled but can't find App.Config, so I can't test it.

    So I'm wondering if you can let me know the way how to generate App.Config from the code for me to manipulate/change each element and figure out how to work the C# classes derived from ConfigurationSection, ConfigurationElement and ConfigurationElementCollection.


    Wednesday, October 3, 2018 3:22 PM
  • Hello Jeff0803,

    >> I can't find <application_name>.exe.config in the project folder.

    This will be automatically generated and located in the output path of your project (e.g. <Project Folder>\bin\debug folder). The same location where your .exe file is created.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Wednesday, October 3, 2018 3:31 PM

  • 2. Note that the CustomSection class pertains to a configuration file like the following :

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <configSections>
        <section name="CustomSection" type="ConsoleTest.CustomSection, ConsoleTest" />
      </configSections>
    
      <CustomSection fileName="default.txt" maxUsers="20" maxIdleTime="5">
      </CustomSection>
    </configuration>

    How to get this configuration file?

    I want to know how to generate this result from the CustomSection class I posted.


    • Edited by Jeff0803 Wednesday, October 3, 2018 3:44 PM
    Wednesday, October 3, 2018 3:43 PM
  • Yes I found it.

    Thanks^^

    Wednesday, October 3, 2018 3:50 PM
  • Hello Jeff0803,

    1. A config file like the one shown will -not- be automatically generated.

    2. When you add App.Config to your project, what will get generated is a basic default one.

    3. You have to manually insert your custom section(s) into the config file.

    4. Please re-read CoolDadTx's post.

    - Bio.


    Please visit my blog : http://limbioliong.wordpress.com/

    Wednesday, October 3, 2018 3:52 PM
  • To generate a config entry for your app you add a new item of type Application Configuration File. This will generate the app.config file into your code. DO NOT rename this file. At build time the compiler will rename the file to <app>.exe.config and place it into your output directory automatically.

    To actually use your custom configuration section you'll need to add an entry to the <configurationSections> element of your config. The article I linked to shows how to do this. Then you'll actually add the configuration section to your config file.


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Jeff0803 Wednesday, October 3, 2018 5:08 PM
    Wednesday, October 3, 2018 4:00 PM
    Moderator
  • To generate a config entry for your app you add a new item of type Application Configuration File. This will generate the app.config file into your code. DO NOT rename this file. At build time the compiler will rename the file to <app>.exe.config and place it into your output directory automatically.

    To actually use your custom configuration section you'll need to add an entry to the <configurationSections> element of your config. The article I linked to shows how to do this. Then you'll actually add the configuration section to your config file.

    So you mean to say that we can make Configuration-related class refer to the App.Config file and it's impossible to create custom configuration file from the Configuration-Related class, is it correct?
    Wednesday, October 3, 2018 5:08 PM
  • The Configuration class is ultimately used to load a config file so yes that is the class you end up using (or ConfigurationManager which is a singleton instance). 

    "it's impossible to create custom configuration file from the Configuration-Related class, is it correct?"

    I don't follow you here. Configuration can be used to load any (valid) .config file. If you want to create an instance of Configuration against a file that doesn't exist then no you cannot do that. Configuration has no public constructors that allow you to do this. ConfigurationManager only has static methods to open an existing file. 

    For creating a "new" file you'd basically end up having to create a skeleton config file. Then you could load that into Configuration. From there you can interact with the sections that were defined and ultimately you can save the config file changes. The Configuration class does expose the defined Sections and you can add more (but I've never tried it). So you could programmatically build a new configuration file given a base configuration file. You'd have to be real careful though as you'd have to ensure the sections are added properly, any custom sections have their handler registered with the file and you'll likely be working with types that normally don't work this way. 

    The configuration subsystem has always supported saving changes but it is hit or miss which sections actually support it. In my experience many custom sections don't support setting the properties, just getting. So you'll likely end up having to drop down to the ConfigurationElement to get everything to work properly.

    Perhaps you could clarify the actual problem you're trying to solve so we could provide better directions. At this point I don't think building an (arbitrary) configuration file programmatically makes sense. If you have a template configuration file that you'd like to tweak though (e.g. changing settings or connection strings) then you can just load it up into Configuration and make the specific changes you need. Then use SaveAs to save as a new file. This is probably the route I'd go.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, October 3, 2018 5:24 PM
    Moderator