.NET Config Files configSource поза папкою каталогу програм


82

У мене є дві програми - одна консольна, а інша - програма ASP.NET. Їм обом потрібно знати одні й ті ж appSettings і connectionStrings. Тому в ідеалі я хотів би використовувати властивість configSource файлів app.config / web.config, щоб вказати це на центральне розташування. Наприклад

<connectionStrings configSource="D:\connectionStrings.config"/>
<appSettings configSource="D:\appSettings.config"/>

Однак це не вдається з помилкою:

Недійсний атрибут configSource .: Недійсний файл configSource 'D: \ appSettings.config'. Він повинен посилатися на файл у тому ж каталозі або в підкаталозі, що і файл конфігурації.

Чи є в будь-якому випадку все-таки використовувати менеджери конфігурацій appSettings / connectionStrings і отримувати значення із зовнішнього розташування?
Я задоволений необхідністю додавати код для цього, але я не хочу замінювати всю систему диспетчера конфігурацій.

Відповіді:


103

Іншим рішенням є просто додати файл конфігурації до всіх ваших проектів як посилання, а не фактично копіювати файл у ваші проекти. Потім встановіть для "Дії побудови" файлу значення "Вміст", а для "Копіювати в каталог виводу" значення "Копіювати, якщо нове", а при компіляції проекту файл буде розміщений у вихідному каталозі.

Щоб додати файл як посилання у діалоговому вікні «Додати існуючий елемент», є кнопка Додати зі спадним меню. Виберіть "Додати як посилання" зі спадного меню кнопки "Додати", щоб завершити процес.


приємно - людям зрозуміти набагато легше, ніж моєму
Роберт Маклін

10
привіт, мені подобається ця відповідь і я намагався застосувати її до свого власного проекту, і, здається, все працює нормально, коли я "публікую" свій додаток (db.config копіюється в webroot, як ти вже сказав), але не під час налагодження через VS & Кассіні. Натомість я отримую виняток "Неможливо відкрити файл configSource 'db.config'". Чи є щось, чого мені не вистачає, щоб зробити це? Дякую!
Funka

16
Звичайно, лише відразу після того, як я вирішив розбити і розмістити коментар з проханням про допомогу, я потім з’ясовую це відразу після цього. Я помітив, що моя db.config також скопійована в папку / bin /, тому я оновив свою web.config, щоб додати цей шлях до свого, configSourceі все здається добре. Знову дякую!
Funka

1
@Funka - Перевірте, чи не виникає у вас проблеми, оскільки для властивості "Дія побудови" вашого db.config встановлено значення "Немає" замість "Вміст", як за замовчуванням web.config. Я вважаю, що налаштування повинні бути "Дія побудови" = "Вміст" та "Копіювати до каталогу виводу" = "Не копіювати".
bopapa_1979

1
Здається, це не працює під час налагодження у VS 2013. Я спробував рішення Erics, і це також не спрацювало.
Chris Nevill

34

У розділі appSettings ви можете використовувати файл = замість configSource =


1
Відмінна знахідка для мене! Дякую!! За допомогою цього я можу замінити вибрані клавіші в AppSettings, як показано на weblogs.asp.net/pwilson/archive/2003/04/09/5261.aspx
Саураб Кумар,

16

Здається, так воно і є. configSource повинен бути в тій же папці або глибше.

Ви можете , хоча я не впевнений, що ви повинні , використовувати жорстке посилання NTFS. [божевільна усмішка]


10

Visual Studio 2015

Якщо у вас виникла ця проблема з Web.Config, прийнята відповідь є правильною, але просто для розширення, оскільки це змусило мене дати собі обличчя:

Коли ви додаєте файл .config до свого проекту за допомогою "Додати як посилання", а потім встановлюєте властивість Копіювати посилання на "Копіювати, якщо новіше" або "Копіювати завжди", тоді фізичний файл буде скопійовано в папку / bin.

Таким чином, коли у вас є розділ конфігурації, визначений у Web.Config, таким чином:

 <section name="mySpecialConfig" type="System.Configuration.AppSettingsSection" requirePermission="false" />

тоді ви повинні визначити відповідний елемент конфігурації таким чином:

  <mySpecialConfig configSource="bin\MySpecialConfig.config">
  </mySpecialConfig>

такі, що configSource вказує на фізичний файл bin \ MySpecialConfig.config, а не на посилання. Також зверніть увагу, що шлях є відносним фізичним шляхом.

Це може здатися смішно очевидним, але якщо ви не робили цього раніше, ніж фізичний файл ще не в папці \ bin, то він може не натиснути відразу.


8

Ви можете завантажити конфігурацію з довільного розташування, але вона не буде доступна через статичні властивості ConfigurationManager:

Configuration myConfig = ConfigurationManager.OpenExeConfiguration(path)

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

Втрата статичних властивостей означає, що весь код повинен знати про різну конфігурацію.


Для цього потрібно завантажити весь конфігураційний файл. Мені потрібно лише, щоб appSettings & connectionStrings були однаковими, решта файлів відрізняється для кожної програми, тому це не вирішує проблему.
Роберт Маклін

Вся конфігурація в будь-якому випадку завантажується звичайними (статичними) властивостями, тому це не робить реальної різниці.
Річард

Крім того, ви можете просто використовувати свій власний формат XML і додати його ім'я до файлів конфігурації програм і прочитати його безпосередньо.
Річард

5

У випадку рядків підключення дійсно можна вказати на спільний файл. Якщо спільний файл знаходиться в мережі UNC, він вимагає адміністративних привілеїв на машині, де розміщуватиметься програма.

Рішення. У веб-файлі web.config використовуйте configSource, щоб вказати на локальний файл конфігурації. Через обмеження .Net це повинно бути на рівні кореневого конфігураційного файлу або нижче. Я просто вказую на файл у самій папці програми:

<connectionStrings configSource="ConnectionStrings.config" />

У спільному розташуванні, яке доступне користувачеві пулу програм, додайте файл конфігурації, що містить спільні рядки підключення. Цей файл не повинен містити жодного xml, крім самого розділу connectionStrings. Спільний файл ConnectionStrings.config виглядає так:

<connectionStrings>
    <clear/>
    <add name="connString1" connectionString="connString1 info goes here"/>
    <add name="connString2" connectionString="connString2 info goes here"/>
</connectionStrings>  

Тепер фокус. Створіть символічне посилання Windows у папці програми, вказуючи на зовнішній спільний конфігураційний файл. Для цього вам знадобляться права адміністратора:

mklink ConnectionStrings.config \\someServer\someShare\someFolder\ConnectionStrings.config

Ми щойно перехитрили .Net. Система конфігурації використовуватиме налаштування configSource для пошуку рядків підключення в локальному файлі, який називається ConnectionStrings.config. Символічне посилання виглядає як файл у .Net, а символічне посилання переходить у спільний файл конфігурації.

Застереження. Зміни у спільному файлі не викликають автоматичного перезапуску програми в .Net. У випадку IIS веб-сайт або пул програм потрібно буде перезапустити вручну.

Через необхідність адміністративних привілеїв для створення символічного посилання, цей підхід може працювати не для всіх. Є дві пов’язані альтернативи, які можуть працювати, якщо спільний файл знаходиться на одному логічному диску - жорсткі посилання та розв’язки. Дивіться цю дискусію та цю дискусію для отримання додаткової інформації.


3

Ви можете розмістити обидва налаштування в machine.config, і тоді вони будуть доступні для всіх ваших програм на сервері.


Це варіант, але я не хочу (потрібні) налаштування, доступні для інших програм на машині. Турбуються рядки підключення, вони мають досить загальні імена, які можуть суперечити іншим програмам.
Роберт Маклін

2

Рішення, яке, як мені здалося, працювало найкраще, було помістити "загальні" конфігураційні файли в центральні файли, а потім скористатися подією попередньої збірки у Visual Studio, щоб скопіювати їх у відповідну папку кожного проекту, який у цьому потребував.


2

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

(Ви можете направити тестовий запуск на копіювання файлів і каталогів у каталог тестового запуску, відредагувавши файл .testrunconfig.)

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


1

Ви можете використовувати fileатрибут, а неconfigSource

Там хороша стаття тут на нього

Це дозволяє вказати відносний шлях таким чином

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings file="..\..\..\..\..\..\ExternalFile.config"></appSettings>
</configuration>

Шлях відносно вихідного каталогу.

Потім у ExternalFile.config ви просто додаєте appSettingsрозділ

<appSettings>
    <add key="SomeKey" value="alue"/>
</appSettings>
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.