Конфигурационные файлы .NET configSource вне папки каталога приложения

У меня есть два приложения - одно консольное приложение, а другое - приложение ASP.NET. Оба они должны знать те же настройки приложения и connectionStrings. Поэтому в идеале я хотел бы использовать свойство configSource файлов app.config/web.config, чтобы указать на центральное расположение. Например

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

Что-то не получается с ошибкой:

Неверный атрибут configSource. Неверный параметр configSource 'D:\appSettings.config. Он должен ссылаться на файл в том же каталоге или в подкаталоге в качестве файла конфигурации.

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

Ответ 1

Другим решением является просто добавить файл конфигурации во все ваши проекты в качестве ссылки вместо фактического копирования файла в ваши проекты. Затем установите "Действие сборки" файла в "Контент" и "Копировать в выходной каталог" на "Копировать, если новый", и когда вы скомпилируете проект, у вас будет файл в выходном каталоге.

Чтобы добавить файл в качестве ссылки, выберите "Добавить в качестве ссылки" в диалоговом окне "Добавить существующий элемент".

Ответ 2

В appSettings вы можете использовать file = вместо configSource =

Ответ 3

Кажется, что так оно и есть. configSource должен находиться в одной и той же папке или глубже.

Вы могли бы, хотя я не уверен, что вам следует использовать жесткую ссылку NTFS. [безумная усмешка]

Ответ 4

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

Configuration myConfig = ConfigurationManager.OpenExeConfiguration(path)

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

Потеря статических свойств означает, что весь код должен знать о другой конфигурации.

Ответ 5

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, чтобы он не сразу щелкнул.

Ответ 6

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

Ответ 7

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

Ответ 8

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

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

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

Ответ 9

В случае строк подключения действительно можно указать общий файл. Если общий файл находится в сети 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 веб-сайт или пул приложений необходимо будет перезапустить вручную.

Из-за необходимости административных привилегий создавать символическую ссылку, этот подход может не работать для всех. Существуют две связанные альтернативы, которые могут работать, если общий файл находится на одном логическом диске - жесткие ссылки и соединения. Подробнее см. эту дискуссию и эту дискуссию.