Конфигурация .NET (app.config / web.config / settings.settings)

У меня есть. NET приложение, которое имеет различные файлы конфигурации для сборок Debug и Release. E. г. приложение отладки. Конфигурационный файл указывает на разработку SQL Server , в которой включена отладка, а цель выпуска указывает на работающий SQL Server. Есть и другие настройки, некоторые из которых отличаются в отладке / выпуске.

В настоящее время я использую два отдельных файла конфигурации (отладка. приложение. Конфиг и релиз. приложение. конфигурации). У меня есть событие сборки проекта, в котором говорится, что если это сборка релиза, то скопируйте релиз. приложение. Конфиг для приложения. конфиг, иначе копировать отладку. приложение. Конфиг для приложения. конфигурации.

Проблема в том, что приложение, похоже, получает свои настройки из настроек. Файл настроек, так что я должен открыть настройки. настройки в Visual Studio, которая затем подсказывает мне, что настройки изменились, поэтому я принимаю изменения, сохраняю настройки. настройки и придется восстановить, чтобы он использовал правильные настройки.

Существует ли лучший / рекомендуемый / предпочтительный метод для достижения аналогичного эффекта? Или в равной степени я подошел к этому совершенно неправильно, и есть ли лучший подход?

вопрос задан 25.09.2008
Gavin
1191 репутация

13 ответов


  • 59 рейтинг

    Любая конфигурация, которая может отличаться в разных средах, должна храниться на уровне компьютера , а не на уровне приложения . (Подробнее об уровнях конфигурации. )

    Это элементы конфигурации, которые я обычно храню на уровне машины:

    Когда каждая среда (разработчик, интеграция, тестирование, этап, оперативная среда) имеет свои уникальные параметры в c: \ Windows \ Microsoft. NET \ Framework64 \ v2. 0. 50727 \ CONFIG , то вы можете рекламировать свой код приложения между средами без каких-либо модификаций после сборки.

    И очевидно, что содержимое каталога CONFIG на уровне компьютера получает управление версиями в другом хранилище или структуре папок из вашего приложения. Вы можете сделать свой. Конфигурационные файлы более удобны для управления исходным кодом благодаря интеллектуальному использованию configSource .

    Я занимаюсь этим уже 7 лет на более чем 200 ASP. NET приложения в 25+ разных компаний. (Не пытаясь похвастаться, просто хочу сообщить, что я никогда не видел ситуации, когда этот подход не работает . )

    ответ дан Portman, с репутацией 20960, 7.01.2009
  • 50 рейтинг

    Это может помочь некоторым людям, имеющим дело с настройками. Настройки и приложение. config: следите за атрибутом GenerateDefaultValueInCode на панели свойств при редактировании любых значений в настройках. сетка настроек в Visual Studio (Visual Studio 2008 в моем случае).

    Если для параметра GenerateDefaultValueInCode установлено значение True (здесь по умолчанию используется значение True! ), значение по умолчанию компилируется в EXE (или DLL), вы можете найти его встроенным в файл при открытии в текстовом редакторе.

    Я работал над консольным приложением и, если у меня были значения по умолчанию в EXE, приложение всегда игнорировало место файла конфигурации в одном каталоге! Совсем кошмар и никакой информации об этом по всему интернету.

    ответ дан Roman, с репутацией 551, 26.08.2009
  • 33 рейтинг

    Здесь есть связанный вопрос:

    Улучшение процесса сборки

    Конфиг-файлы поставляются с возможностью переопределения настроек:

    
    

    Вместо того, чтобы регистрировать два файла (или более), вы регистрируете только файл конфигурации по умолчанию, а затем на каждом целевом компьютере ставите Local. config, только с разделом appSettings, который имеет переопределения для этого конкретного компьютера.

    Если вы используете разделы конфигурации, эквивалент:

    configSource="Local.config"
    

    Конечно, это хорошая идея сделать резервные копии всех локальных. Конфигурационные файлы с других машин и проверьте их где-нибудь, но не как часть реальных решений. Каждый разработчик ставит «игнорировать» на Local. Конфигурационный файл, чтобы он не регистрировался, что переписало бы файл всех остальных.

    (Вы на самом деле не должны называть это "Локальный. конфиг ", вот что я использую)

    ответ дан Eric Z Beard, с репутацией 27206, 25.09.2008
  • 14 рейтинг

    Из того, что я читаю, похоже, что вы используете Visual Studio для процесса сборки. Задумывались ли вы об использовании MSBuild и Nant вместо этого?

    Синтаксис Нанта в xml немного странный, но как только вы его понимаете, то, что вы упомянули, становится довольно тривиальным.

    
        
    
        
            
        
    
        
            
        
    
        
            
        
    
    
    
    ответ дан Steven Williams, с репутацией 675, 25.09.2008
  • 11 рейтинг

    Мне кажется, что вы можете извлечь выгоду из Visual Studio 2005 Web Deployment Project s.

    С этим, вы можете сказать ему, чтобы обновить / изменить разделы вашей сети. Конфигурационный файл в зависимости от конфигурации сборки.

    Посмотрите на эту запись в блоге от Скотта Гу для быстрого обзора / образца.

    ответ дан Magnus Johansson, с репутацией 20938, 25.09.2008
  • 8 рейтинг

    Мы использовали проекты веб-развертывания, но с тех пор перешли на NAnt. Вместо того, чтобы разветвлять и копировать различные файлы настроек, мы в настоящее время встраиваем значения конфигурации непосредственно в скрипт сборки и внедряем их в наши файлы конфигурации с помощью задач xmlpoke:

      
    

    В любом случае ваши конфигурационные файлы могут иметь любые значения разработчика, которые вы хотите, и они будут нормально работать в вашей среде разработки, не нарушая ваших производственных систем. Мы обнаружили, что разработчики с меньшей вероятностью произвольно изменяют переменные сценария сборки при тестировании, поэтому случайные неправильные конфигурации встречаются реже, чем при использовании других техник, которые мы пробовали, хотя по-прежнему необходимо добавлять каждую переменную в начале процесса, чтобы Значение dev по умолчанию не выдвигается в prod.

    ответ дан jasondoucette, с репутацией 891, 25.09.2008
  • 7 рейтинг

    Мой текущий работодатель решил эту проблему, сначала поместив уровень dev (отладка, stage, live и т. Д.) В машину. Конфигурационный файл Затем они написали код, чтобы подобрать его и использовать правильный файл конфигурации. Это решило проблему с неверной строкой подключения после развертывания приложения.

    Недавно они написали центральный веб-сервис, который возвращает правильную строку соединения из значения в машине. значение конфигурации

    Это лучшее решение? Наверное, нет, но у них это работает.

    ответ дан Hector Sosa Jr, с репутацией 3922, 25.09.2008
  • 5 рейтинг

    Одним из решений, которое мне помогло, было использование WebDeploymentProject. У меня было 2/3 разных веб. Конфигурационные файлы на моем сайте и при публикации, в зависимости от выбранного режима конфигурации (выпуск / постановка / и т.д. , , ) Я бы скопировал через Интернет. Релиз. Конфиг и переименуйте его в сеть. config в событии AfterBuild и удалите ненужные мне (Web. Поэтапное. конфиг например).

    
        
        
        
        
        
        
        
      
    
    ответ дан Adam Vigh, с репутацией 970, 25.09.2008
  • 3 рейтинг

    У нашего proj есть та же проблема, где мы должны были поддерживать конфиги для dev, qa, uat и prod. Вот что мы следовали (применимо, только если вы знакомы с MSBuild):

    Использовать MSBuild с расширением задач MSBuild Community. Он включает в себя задачу «XmlMassUpdate», которая может «массово обновлять» записи в любом файле XML, как только вы дадите ему правильный узел для запуска.

    Выполнить:

    1) У вас должен быть один конфигурационный файл, в котором будут ваши записи dev env; это файл конфигурации в вашем решении.

    2) Вы должны иметь 'Замены. XML-файл, который содержит только записи, которые являются РАЗЛИЧНЫМИ (в основном appSettings и ConnectionStrings) для каждой среды. Записи, которые не изменяются в разных средах, не нужно помещать в этот файл. Они могут жить в сети. Конфигурационный файл решения и не будет затронут заданием

    3) В файле сборки просто вызовите задачу массового обновления XML и укажите в качестве параметра правильную среду.

    См. Пример ниже:

        
        
            
            
        
    
        
        
          
            
               
                
                           
            
            
              
                
                          
            
         
        
    
    
    
    
        
                
            
    

    заменить '$ Environment' на 'QA' или 'Prod' в зависимости от того, что env. Вы строите для. Обратите внимание, что вы должны работать с копией файла конфигурации, а не с самим файлом конфигурации, чтобы избежать возможных ошибок, которые невозможно исправить.

    Просто запустите файл сборки, а затем переместите обновленный файл конфигурации в среду развертывания, и все готово!

    Для лучшего обзора прочитайте это:

    http: // blogs. Microsoft. сотрудничество. иль / блог / dorony / Архив / 2008/01/18 / простая конфигурация развертывания-с MSBuild-и-в-xmlmassupdate-задачей. aspx

    ответ дан Punit Vora, с репутацией 3044, 18.06.2009
  • 3 рейтинг

    Здесь вы найдете другое решение: Лучший способ переключения конфигурации между средами разработки / UAT / Prod в ASP. СЕТЬ? , который использует XSLT для преобразования сети. конфигурации.

    Есть также несколько хороших примеров использования NAnt.

    ответ дан Aaron Powell, с репутацией 20199, 25.09.2008
  • 2 рейтинг

    Как и вы, я также настроил «мульти» приложение. Конфиг - например, приложение. configDEV, приложение. configTEST, приложение. конфигурации. МЕСТНЫЙ. Я вижу некоторые из предложенных отличных альтернатив, но если вам нравится, как это работает для вас, я бы добавил следующее:

    У меня есть

    для каждого приложения я добавляю это в пользовательский интерфейс в заголовке окна: из ConfigurationManager. AppSettings. Получить ( "Env");

    Я просто переименую конфигурацию в ту, на которую нацеливаюсь (у меня есть проект с 8 приложениями с большим количеством настроек базы данных / wcf против 4 событий). Для развертывания с помощью clickonce в каждом я меняю настройки 4g в проекте и захожу. (это я хотел бы автоматизировать)

    Единственное, что мне нужно - это помнить, что нужно «очистить все» после изменения, так как старый конфиг «застрял» после ручного переименования. (Что, я думаю, исправит ваши настройки. постановка вопроса).

    Я считаю, что это работает очень хорошо (однажды у меня будет время взглянуть на MSBuild / NAnt)

    ответ дан tdrake, с репутацией 672, 26.02.2009
  • 0 рейтинг

    Web. конфиг:

    Интернет. Конфигурация необходима, когда вы хотите разместить свое приложение на IIS. Web. config - это обязательный конфигурационный файл для IIS, чтобы настроить поведение обратного прокси-сервера перед Kestrel. Вы должны поддерживать сеть. Конфиг, если вы хотите разместить его на IIS.

    AppSetting. JSON:

    Для всего остального, что не касается IIS, вы используете AppSetting. JSON. AppSetting. JSON используется для Asp. Net Core хостинг. ASP. NET Core использует переменную среды «ASPNETCORE_ENVIRONMENT» для определения текущей среды. По умолчанию, если вы запускаете приложение без установки этого значения, оно автоматически по умолчанию будет работать в производственной среде и будет использовать «AppSetting». производство. JSON "файл. Когда вы отлаживаете через Visual Studio, он устанавливает среду разработки, поэтому он использует «AppSetting. JSON». Посетите этот сайт, чтобы понять, как установить переменную среды хостинга в Windows.

    App. конфиг:

    App. config - это еще один файл конфигурации, используемый. NET, который в основном используется для Windows Forms, Windows Services, консольных приложений и приложений WPF. Когда вы начинаете свой Asp. Net Core хостинг через консольное приложение. Конфиг также используется.


    TL; DR

    Выбор файла конфигурации определяется средой размещения, выбранной вами для службы. Если вы используете IIS для размещения своей службы, используйте Интернет. Конфигурационный файл Если вы используете любую другую среду хостинга, используйте приложение. Конфигурационный файл См. Настройка служб с использованием документации по файлам конфигурации а также проверить Конфигурация в ASP. NET Core.

    ответ дан Alper Ebicoglu, с репутацией 2687, 10.09.2018
  • 0 рейтинг

    Это говорит асп. выше, так почему бы не сохранить настройки в базе данных и использовать специальный кеш для их получения?

    Причина, по которой мы сделали это, заключается в том, что (для нас) проще постоянно обновлять базу данных, чем получать разрешение на постоянное обновление производственных файлов.

    Пример пользовательского кэша:

    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(out config))
            {
                config = new Configurations();
                config.List(SNCLavalin.US.Common.Enumerations.ConfigurationSection.AppSettings);
                cache.AddToCache(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
        {
            #region CONSTRUCTORS
    
            public Configurations() : base()
            {
                initialize();
            }
            public Configurations(int capacity) : base(capacity)
            {
                initialize();
            }
            public Configurations(IEnumerable 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);
            }
    
            /// 
    /// Lists one-to-many records. ///
     
            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
        }
    }
    
    ответ дан Prisoner ZERO, с репутацией 7000, 24.05.2011