.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 копируется в корневой каталог, как вы сказали), но не при отладке через VS И Кассини. Вместо этого я получаю исключение «Невозможно открыть файл configSource 'db.config'». Что-то мне не хватает, чтобы это сделать? Благодаря!
Funka
16
Конечно, только сразу после того, как я решил сломаться и опубликовать комментарий с просьбой о помощи, я сразу понял это. Я заметил, что мой db.config также скопирован в папку / bin /, поэтому я обновил свой web.config, добавив в него этот путь, configSourceи все выглядит хорошо. Еще раз спасибо!
Funka
1
@Funka - проверьте, не возникла ли у вас проблема, потому что для свойства "Build Action" вашего db.config установлено значение "None" вместо "Content", как в web.config по умолчанию. Я считаю, что настройки должны быть «Действие сборки» = «Содержимое» и «Копировать в выходной каталог» = «Не копировать».
bopapa_1979
1
Кажется, это не работает при отладке в VS 2013. Я пробовал решение Erics, и оно тоже не сработало.
Крис Невилл
34

В appSettings вы можете использовать file = вместо 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, он может не щелкнуть сразу.

Serexx
источник
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, и тогда они будут доступны для всех ваших приложений на сервере.

Freggel
источник
Это вариант, но мне не нужны (не нужны) настройки, доступные для других приложений на машине. Беспокойство вызывают строки подключения, они имеют довольно общие имена, которые могут конфликтовать с другими приложениями.
Роберт Маклин,
2

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

Роберт Маклин
источник
2

У меня была серьезная борьба с этой проблемой, но я нашел здесь хорошее решение: тестовый запуск с внешней конфигурацией

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

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

marcel_g
источник
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>
Алекс
источник