.NET Configuration (app.config/web.config/settings.settings)

后端 未结 13 1251
广开言路
广开言路 2020-11-29 14:41

I have a .NET application which has different configuration files for Debug and Release builds. E.g. the debug app.config file points to a development SQL Server which has d

相关标签:
13条回答
  • 2020-11-29 15:21

    Our project has the same issue where we had to maintain configs for dev, qa, uat and prod. Here is what we followed (only applies if you are familiar with MSBuild):

    Use MSBuild with the MSBuild Community tasks extension. It includes the 'XmlMassUpdate' task that can 'mass-update' entries in any XML file once you give it the correct node to start with.

    To Implement:

    1) You need to have one config file which will have your dev env entries; this is the config file in your solution.

    2) You need to have a 'Substitutions.xml' file, that contains only the entries that are DIFFERENT (appSettings and ConnectionStrings mostly) for each environment. Entries that do not change across the environment need not be put in this file. They can live in the web.config file of the solution and will not be touched by the task

    3) In your build file, just call the XML mass update task and provide the right environment as a parameter.

    See example below:

        <!-- Actual Config File -->
        <appSettings>
            <add key="ApplicationName" value="NameInDev"/>
            <add key="ThisDoesNotChange" value="Do not put in substitution file" />
        </appSettings>
    
        <!-- Substitutions.xml -->
        <configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
          <substitutions>
            <QA>
               <appSettings>
                <add xmu:key="key" key="ApplicationName" value="NameInQA"/>
               </appSettings>            
            </QA>
            <Prod>
              <appSettings>
                <add xmu:key="key" key="ApplicationName" value="NameInProd"/>
              </appSettings>            
            </Prod>
         </substitutions>
        </configuration>
    
    
    <!-- Build.xml file-->
    
        <Target Name="UpdateConfigSections">
                <XmlMassUpdate ContentFile="Path\of\copy\of\latest web.config" SubstitutionsFile="path\of\substitutionFile" ContentRoot="/configuration" SubstitutionsRoot="/configuration/substitutions/$(Environment)" />
            </Target>
    

    replace '$Environment' with 'QA' or 'Prod' based on what env. you are building for. Note that you should work on a copy of a config file and not the actual config file itself to avoid any possible non-recoverable mistakes.

    Just run the build file and then move the updated config file to your deployment environment and you are done!

    For a better overview, read this:

    http://blogs.microsoft.co.il/blogs/dorony/archive/2008/01/18/easy-configuration-deployment-with-msbuild-and-the-xmlmassupdate-task.aspx

    0 讨论(0)
  • 2020-11-29 15:23

    From what I am reading, it sounds like you are using Visual Studio for your build process. Have you thought about using MSBuild and Nant instead?

    Nant's xml syntax is a little weird but once you understand it, doing what you mentioned becomes pretty trivial.

    <target name="build">
        <property name="config.type" value="Release" />
    
        <msbuild project="${filename}" target="Build" verbose="true" failonerror="true">
            <property name="Configuration" value="${config.type}" />
        </msbuild>
    
        <if test="${config.type == 'Debug'}">
            <copy file=${debug.app.config}" tofile="${app.config}" />
        </if>
    
        <if test="${config.type == 'Release'}">
            <copy file=${release.app.config}" tofile="${app.config}" />
        </if>
    
    </target>
    
    0 讨论(0)
  • 2020-11-29 15:24

    To me it seems that you can benefit from the Visual Studio 2005 Web Deployment Projects.

    With that, you can tell it to update/modify sections of your web.config file depending on the build configuration.

    Take a look at this blog entry from Scott Gu for a quick overview/sample.

    0 讨论(0)
  • 2020-11-29 15:36

    It says asp.net above, so why not save your settings in the database and use a custom-cache to retrieve them?

    The reason we did it because it's easier (for us) to update the continuously database than it is to get permission to continuously update production files.

    Example of a Custom Cache:

    public enum ConfigurationSection
    {
        AppSettings
    }
    
    public static class Utility
    {
        #region "Common.Configuration.Configurations"
    
        private static Cache cache = System.Web.HttpRuntime.Cache;
    
        public static String GetAppSetting(String key)
        {
            return GetConfigurationValue(ConfigurationSection.AppSettings, key);
        }
    
        public static String GetConfigurationValue(ConfigurationSection section, String key)
        {
            Configurations config = null;
    
            if (!cache.TryGetItemFromCache<Configurations>(out config))
            {
                config = new Configurations();
                config.List(SNCLavalin.US.Common.Enumerations.ConfigurationSection.AppSettings);
                cache.AddToCache<Configurations>(config, DateTime.Now.AddMinutes(15));
            }
    
            var result = (from record in config
                          where record.Key == key
                          select record).FirstOrDefault();
    
            return (result == null) ? null : result.Value;
        }
    
        #endregion
    }
    
    namespace Common.Configuration
    {
        public class Configurations : List<Configuration>
        {
            #region CONSTRUCTORS
    
            public Configurations() : base()
            {
                initialize();
            }
            public Configurations(int capacity) : base(capacity)
            {
                initialize();
            }
            public Configurations(IEnumerable<Configuration> collection) : base(collection)
            {
                initialize();
            }
    
            #endregion
    
            #region PROPERTIES & FIELDS
    
            private Crud _crud; // Db-Access layer
    
            #endregion
    
            #region EVENTS
            #endregion
    
            #region METHODS
    
            private void initialize()
            {
                _crud = new Crud(Utility.ConnectionName);
            }
    
            /// <summary>
            /// Lists one-to-many records.
            /// </summary>
            public Configurations List(ConfigurationSection section)
            {
                using (DbCommand dbCommand = _crud.Db.GetStoredProcCommand("spa_LIST_MyConfiguration"))
                {
                    _crud.Db.AddInParameter(dbCommand, "@Section", DbType.String, section.ToString());
    
                    _crud.List(dbCommand, PopulateFrom);
                }
    
                return this;
            }
    
            public void PopulateFrom(DataTable table)
            {
                this.Clear();
    
                foreach (DataRow row in table.Rows)
                {
                    Configuration instance = new Configuration();
                    instance.PopulateFrom(row);
                    this.Add(instance);
                }
            }
    
            #endregion
        }
    
        public class Configuration
        {
            #region CONSTRUCTORS
    
            public Configuration()
            {
                initialize();
            }
    
            #endregion
    
            #region PROPERTIES & FIELDS
    
            private Crud _crud;
    
            public string Section { get; set; }
            public string Key { get; set; }
            public string Value { get; set; }
    
            #endregion
    
            #region EVENTS
            #endregion
    
            #region METHODS
    
            private void initialize()
            {
                _crud = new Crud(Utility.ConnectionName);
                Clear();
            }
    
            public void Clear()
            {
                this.Section = "";
                this.Key = "";
                this.Value = "";
            }
            public void PopulateFrom(DataRow row)
            {
                Clear();
    
                this.Section = row["Section"].ToString();
                this.Key = row["Key"].ToString();
                this.Value = row["Value"].ToString();
            }
    
            #endregion
        }
    }
    
    0 讨论(0)
  • 2020-11-29 15:38

    Like you I've also set up 'multi' app.config - eg app.configDEV, app.configTEST, app.config.LOCAL. I see some of the excellent alternatives suggested, but if you like the way it works for you, I'd add the following:

    I have a
    <appSettings>
    <add key = "Env" value = "[Local] "/> for each app I add this to the UI in the titlebar: from ConfigurationManager.AppSettings.Get("Env");

    I just rename the config to the one I'm targetting (I have a project with 8 apps with lots of database/wcf config against 4 evenioments). To deploy with clickonce into each I change 4 seetings in the project and go. (this I'd love to automate)

    My only gotcha is to remember to 'clean all' after a change, as the old config is 'stuck' after a manual rename. (Which I think WILL fix you setting.setting issue).

    I find this works really well (one day I'll get time to look at MSBuild/NAnt)

    0 讨论(0)
  • 2020-11-29 15:41

    This might help some people dealing with Settings.settings and App.config: Watch out for GenerateDefaultValueInCode attribute in the Properties pane while editing any of the values in the Settings.settings grid in Visual Studio (Visual Studio 2008 in my case).

    If you set GenerateDefaultValueInCode to True (True is the default here!), the default value is compiled into the EXE (or DLL), you can find it embedded in the file when you open it in a plain text editor.

    I was working on a console application and if I had defaulted in the EXE, the application always ignored the configuration file placed in the same directory! Quite a nightmare and no information about this on the whole Internet.

    0 讨论(0)
提交回复
热议问题