Файли app.config / web.config для розробників у Visual Studio


93

У нас є декілька проектів .NET, де ми зберігаємо певні параметри у файлах конфігурації.

Тепер кожен розробник матиме власні конфігураційні файли, які трохи відрізняються (різні рядки підключення для підключення до локальних баз даних, різні кінцеві точки WCF тощо)

На даний момент ми схильні перевіряти файли app / web.config та модифікувати їх відповідно до наших потреб.

Це призводить до багатьох проблем, оскільки час від часу хтось перевіряє власні налаштування або втрачає власну конфігурацію, отримуючи останню версію з TFS .

Як ти справляєшся з подібними ситуаціями? Або у вас взагалі немає цієї проблеми?


10
Я голосую за те, щоб відкрити його знову, оскільки це є загальною проблемою для розробників візуальних студій і безпосередньо стосується інструментів, які використовують розробники. (звідси голоси)
Крістіан Голлхардт

Погоджено, це постійне питання, оскільки чисельність нашої команди зросла, а різні спроби вирішення були незадовільними.
DiskJunky

Відповіді:


66

Ми використовуємо систему, яка поєднує кілька існуючих відповідей на цій сторінці, а також спирається на цю пропозицію Скотта Хансельмана .

Коротше кажучи, ми зробили загальну програму app.config / web.config та більшість конкретних налаштувань в окремих файлах, як пропонують інші відповіді тут. наприклад, для наших налаштувань SMTP, app.config містить

<system.net>
  <mailSettings>
    <smtp configSource="config\smtp.config" />
  </mailSettings>
</system.net>

Цей файл знаходиться під контролем джерела. Однак окремі файли, подібні до цього, не є:

<?xml version="1.0" encoding="utf-8" ?>
<smtp deliveryMethod="Network">
  <network host="127.0.0.1" port="25" defaultCredentials="false" password="" userName ="" />
</smtp>

На цьому історія не зовсім закінчується. Що можна сказати про нових розробників чи про інсталяцію з новим джерелом? Основна частина конфігурації більше не контролюється джерелом, і дуже важко вручну створювати всі потрібні їм файли .config. Я вважаю за краще мати джерело, яке, принаймні, буде скомпільовано прямо з коробки.

Тому ми зберігаємо версію файлів .config у контролі джерела з назвою .config.default . Тому свіже дерево джерел виглядає так:

текст заміщення

Тим не менше, розробнику це не дуже корисно, оскільки для Visual Studio це просто безглузді текстові файли. Отже, командний файл, copy_default_config.batдбає про створення початкового набору файлів .config із файлів .config.default:

@echo off
@REM Makes copies of all .default files without the .default extension, only if it doesn't already exist. Does the same recursively through all child folders.
for /r %%f in (*.default) do (
    if not exist "%%~pnf" (echo Copying %%~pnf.default to %%~pnf & copy "%%f" "%%~pnf" /y)
)
echo Done.

Сценарій можна безпечно повторно запускати, оскільки розробники, які вже мають свої файли .config, не будуть їх перезаписувати. Тому можна було б запустити цей пакетний файл як подію попередньої збірки. Значення у файлах .default можуть бути не зовсім правильними для нового встановлення, але вони є розумною відправною точкою.

Врешті-решт, що закінчується у кожного розробника, це папка конфігураційних файлів, яка виглядає приблизно так:

текст заміщення

Це може здатися трохи заплутаним, але це, безумовно, краще, ніж клопоти розробників, що наступають один одному на пальці.


Чому б не мати безпосередньо основного .config у сховищі, але не окремих?
graffic

6
Яка біль, для цього нам потрібне краще рішення. У мене був налаштований подібний метод, і я втомився від того, що він був таким крихким і все ще потребував пояснень для нових розробників.
jpierson

@Gavin, я отримую повідомлення про помилку, якщо намагаюся запустити вказаний вами файл bat: "'@ echo" не розпізнається як внутрішня чи зовнішня команда, операційна програма чи пакетний файл.
Остін,

2
@Austin, у вас, здається, є якесь непридатне для друку сміття перед символом '@echo', частиною якого є мітка порядку байтів Unicode? Можливо, щось пішло не так у копіюванні / вставці, або пакетний файл зберігається у кодуванні, яке неможливо прочитати належним чином.
Гевін

21

У вашому Web.config використовуйте джерело з інших файлів

<configuration>
    <connectionStrings configSource="ConnectionStrings.config" />
...
</configuration>

Зберігайте web.config у контролі версій і не робіть цього для ConnectionStrings.config. Тепер у всіх розробників є один файл для рядка підключення.

Ви можете зробити це для всіх налаштувань, які залежать від локальної мережі.


1
Це приємно спрацювало для мене. Дивіться також: davidgiard.com/2012/05/25/… Файл ConnectionStrings.config повинен знаходитися в тій же папці, що і програма або веб-конфігурація. Крім того, ви повинні змінити його властивості на "копіювати, якщо новіші" для виведення. А файл ConnectionStrings.config потребує повного розділу з елементами відкриття та закриття. Вам також потрібно встановити контроль версій, щоб ігнорувати файл, тому кожен з них залежить від користувача.
Джеффрі Раггарден,

1
Я використовував параметр <appSettings file = "..">, оскільки мені довелося об’єднати налаштування
Spikolynn

1
@JeffreyRoughgarden Якщо ви включите файл ConnectionStrings.config у Провідник рішень, чи не повинен файл існувати на файліysysterm? І якщо це так, це означає, що ви перевірили його в контролі джерела. Яка початкова проблема, від якої ми намагалися піти.
Джез

20

Ось рішення для файлів web.config та Visual Studio 2010:

1) Відредагуйте файл .csproj веб-програми, щоб додати таку AfterBuildціль:

  <Project>
   ...
    <Target Name="AfterBuild">
      <Copy SourceFiles="web.config" DestinationFiles="obj\$(Configuration)\tempweb.config" />
      <TransformXml Source="obj\$(Configuration)\tempweb.config"
                  Transform="web.$(USERNAME).config"
                  Destination="obj\$(Configuration)\tempweb2.config" />
      <ReadLinesFromFile File="obj\$(Configuration)\tempweb2.config"><Output TaskParameter="Lines" ItemName="TransformedWebConfig"/></ReadLinesFromFile>
      <ReadLinesFromFile File="web.config"><Output TaskParameter="Lines" ItemName="UnTransformedWebConfig"/></ReadLinesFromFile>
      <Copy Condition=" @(UnTransformedWebConfig) != @(TransformedWebConfig) " SourceFiles="obj\$(Configuration)\tempweb2.config" DestinationFiles="web.config" OverwriteReadOnlyFiles="True" />
    </Target>
  </Project>

Ця ціль перетворить файл Web.config, що відповідає поточному введеному розробнику - отже, $(USERNAME)змінній -, з відповідним файлом, створеним в 1). Він замінить локальний Web.config, лише якщо зміст змінився (щоб уникнути перезапуску) під час кожної збірки, навіть якщо локальний Web.config контролюється джерелом, тому існує OverwriteReadOnlyFiles встановлено значення True. Цей факт фактично є спірним.

2) Створіть файл із іменем Web.[developer windows login].configдля кожного розробника проекту. (наприклад, на наступних скріншотах у мене є два розробники, які називаються smo та smo2):

введіть тут опис зображення

Ці файли (1 на розробника) можуть / повинні контролюватися джерелом. Вони не повинні бути позначені як залежні від основної Web.config, оскільки ми хочемо мати можливість перевірити їх окремо.

Кожен із цього файлу являє собою перетворення, яке застосовується до основного файлу Web.Config. Синтаксис перетворення описаний тут: Web.config Синтаксис перетворення для розгортання проекту веб-додатків . Ми повторно використовуємо це круте завдання перетворення файлів Xml, яке поставляється нестандартно з Visual Studio. Метою цього завдання є злиття елементи та атрибути Xml замість того, щоб перезаписати весь файл.

Наприклад, ось зразок, web.[dev login].configякий змінює рядок підключення з назвою 'MyDB', незалежно від решти файлу Web.config:

<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
    <connectionStrings>
      <add name="MyDB" 
        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 
        xdt:Transform="SetAttributes" xdt:Locator="Match(name)" />
    </connectionStrings>
</configuration>

Зараз це рішення не є ідеальним, оскільки:

  • після побудови розробники можуть мати інший Web.Config локально, ніж у системі керування джерелами
  • їм, можливо, доведеться змусити локальний запис при отриманні нового Web.Config із системи керування джерелом
  • розробники не повинні перевіряти / в основному web.config. Він повинен бути зарезервований для небагатьох людей.

Але принаймні, вам потрібно лише підтримувати унікальний головний web.config плюс один файл перетворення на кожного розробника.

Подібний підхід міг би бути застосований до файлів App.config (не веб-файлів), але я не розробляв далі.


Я перейменував свій Web.config у Web.base.config, створив новий файл Web.config, а потім на кроці 1 змінив з <Copy SourceFiles = "web.config"> на <Copy SourceFiles = "web.base.config". Роблячи це, я можу мати локальний web.config, який можна проігнорувати у контролі джерела.
S. Baggy

Це все ще не ідеально, але я віддаю перевагу іншому рішенню
JMK

Як ви вважаєте, чи можна використовувати а, web.default.configколи web.$(USERNAME).configне існує? До речі, дякую за цю чудову відповідь.
Крістіан Голлхардт,


0

Як щодо ігнорування файлу, щоб він ніколи не реєструвався? Я зіткнувся з подібною проблемою і додав web.config до списку ігнорувань у Subversion.

Однак у TFS це трохи складніше, див. Цю публікацію про те, як це зробити.


0

Одним із способів впоратися є наявність символічної системи та використання сценарію rake для зміни значень.

Більш елементарним методом може бути посилання на файл AppSettings.config для всіх параметрів AppSettings у вашому web.config (аналогічно з підключеннями), тобто

<appSettings configSource="_configs/AppSettings.config" />

Тоді майте папку, у якої кожен із ваших розробників має версію у підпапці (тобто / _configs / dave /). Потім, коли розробник працює над власним кодом, він копіює з підпапки до кореневої частини пов'язаної папки.

Вам потрібно буде переконатись, що ви повідомляєте зміни до цих файлів (якщо ви не зробите лексему). Якщо ви тримаєте файл AppSettings.config поза контролем джерела та перевіряєте лише окремі папки розробників (усі вони), вони будуть змушені скопіювати правильну.

Я віддаю перевагу жетонізації, але можу бути жорсткішим, щоб почати працювати, якщо це призначено лише для швидкого виправлення.


0

Ігноруйте файли та мати Commom_Web.Config та Common_App.Config. Використання сервера безперервної інтеграції із завданнями збірки, які перейменовують ці два на звичайні імена, щоб сервер збірки міг виконувати свою роботу.


це потрібно зробити на машинах розробників, перш ніж перейти до побудови сервера
twarz01

Ніяке це перейменування не повинно відбуватися на сервері збірки. Поширені конфігураційні файли, що зберігаються на диверсії, вони не залежать від конкретного розробника. Тоді як кожен розробник запускає свої особисті конфігураційні файли для розробки на своїй машині, і не дбає про його надсилання, оскільки це не є частиною диверсії.
Arthis

Те, що це не підтримує, - це розробники, що налагоджують програму. Корінь web.configу вихідній папці використовується під час налагодження. Якщо ви, наприклад, додається web.configдо .gitignoreі або потрібна користувачам копіювати Commom_Web.Configв web.configі редагувати їх фантазії, ви частину шляху. Але тоді, коли вам потрібно відредагувати щось, що є однаковим на всіх машинах розробника, наприклад, system.web/compilationрозділ або окреме, appSettingsщо повинно бути однаковим скрізь, ця схема розпадається.
binki

0

У нас однакова проблема, і те, що ми робимо, це

  • Перевірте в web.config із значеннями testserver / production
  • Розробник переходить у провідник Windows і змінює режим лише для читання файлу
  • Відредагуйте конфігурацію відповідно до їх середовища.
  • Реєстрація в web.config відбувається лише тоді, коли змінюються значення розгортання або додається або видаляється будь-який запис конфігурації.
  • Для цього потрібна велика кількість коментарів для кожного запису конфігурації, оскільки його потрібно змінювати кожному розробнику

1
Це може працювати краще в магазинах, де контролер джерела, який ви використовуєте, встановлює поля як "Лише читання" за замовчуванням, але для інших, які використовують Subversion, він також може не працювати. Ми могли б встановити дозволи лише на читання у сховищі, щоб запобігти його фіксації, однак це потрібно було б встановити в кожному файлі конфігурації для кожної гілки.
jpierson

Для тих з нас, хто не використовує щось на зразок TFS, не очевидно, як це рішення могло б працювати. Не могли б ви дати трохи більше довідки? Крім того, хіба це не вимагає від розробників обережності та випадкової перевірки файлу?
binki

-1

Припускаючи, що ви використовуєте Visual Studio, чому б вам не використовувати різні конфігурації рішення? Наприклад: ви можете мати конфігурацію налагодження, яка використовує Web.config.debug, і конфігурацію випуску, яка використовує Web.config.release. Web.config.debug повинен мати щось на зразок

<appSettings file="C:/Standard_Path_To_Configs/Standard_Name_For_Config.config"> 

з файлом Standard_Name_For_Config.config, який містить усі налаштування особистого розробника, тоді як Web.config.release завжди має виробничі налаштування. Ви можете зберігати конфігурації за замовчуванням у якійсь папці, керованій джерелом, і змусити нового користувача взяти їх звідти.


Тоді кожному окремому користувачеві, котрий коли-небудь сприяв би проекту, потрібно було мати власну конфігурацію збірки. Здається, це не масштабується і не підтримує проекти, які приймають внески.
binki
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.