Pliki konfiguracyjne .NET configSource poza folderem katalogu aplikacji

82

Mam dwie aplikacje, jedną aplikację konsoli, a drugą aplikację ASP.NET. Oboje muszą znać te same ustawienia appSettings i connectionStrings. Więc idealnie chciałbym użyć właściwości configSource plików app.config / web.config, aby wskazać to na centralną lokalizację. Na przykład

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

To jednak kończy się niepowodzeniem z błędem:

Atrybut configSource jest nieprawidłowy .: Nieprawidłowy element configSource „D: \ appSettings.config”. Musi odnosić się do pliku w tym samym katalogu lub w podkatalogu co plik konfiguracyjny.

Czy mimo wszystko nadal można używać menedżerów konfiguracji appSettings / connectionStrings i pobierać wartości z lokalizacji zewnętrznej?
Jestem zadowolony, że muszę dodać kod, ale nie chcę wymieniać całego systemu menedżera konfiguracji.

Robert MacLean
źródło

Odpowiedzi:

103

Innym rozwiązaniem jest po prostu dodanie pliku konfiguracyjnego do wszystkich projektów jako łącza zamiast faktycznego kopiowania pliku do projektów. Następnie ustaw „Akcję budowania” pliku na „Zawartość” i „Kopiuj do katalogu wyjściowego” na „Kopiuj, jeśli nowszy”, a po kompilacji projektu plik będzie znajdować się w katalogu wyjściowym.

Aby dodać plik jako łącze w oknie dialogowym „Dodaj istniejący element”, znajduje się przycisk Dodaj z menu rozwijanym. Wybierz „Dodaj jako łącze” z menu rozwijanego na przycisku Dodaj, aby zakończyć proces.

Społeczność
źródło
miły - dużo łatwiejszy do zrozumienia dla ludzi niż mój sposób
Robert MacLean,
10
cześć, podoba mi się ta odpowiedź i próbowałem zastosować ją do mojego własnego projektu i wydaje się, że wszystko działa dobrze, kiedy „publikuję” moją aplikację (db.config jest kopiowany do katalogu głównego, jak powiedziałeś), ale nie podczas debugowania przez VS & Cassini. Zamiast tego pojawia się wyjątek „Nie można otworzyć pliku configSource 'db.config'”. Czy jest coś, czego mi brakuje, aby móc to zrobić? Dzięki!
Funka
16
Oczywiście dopiero po tym, jak zdecyduję się załamać i opublikować komentarz z prośbą o pomoc, zaraz potem to rozumiem. Zauważyłem, że mój plik db.config jest również kopiowany do folderu / bin /, więc zaktualizowałem plik web.config tak, aby poprzedzał tę ścieżkę w jego configSourcei wszystko wydaje się być w porządku. Dzięki jeszcze raz!
Funka
1
@Funka - sprawdź, czy masz problem, ponieważ właściwość „Build Action” twojego db.config jest ustawiona na „None” zamiast „Content”, jak domyślny web.config. Uważam, że ustawienia powinny być następujące: „Akcja tworzenia” = „Treść” i „Kopiuj do katalogu wyjściowego” = „Nie kopiuj”.
bopapa_1979
1
Wydaje się, że to nie działa podczas debugowania w VS 2013. Wypróbowałem rozwiązanie Erics, ale to też nie działa.
Chris Nevill
34

W appSettings możesz użyć file = zamiast configSource =


źródło
1
Doskonałe znalezisko dla mnie! Dzięki!! Dzięki temu mogę nadpisać wybrane klucze w AppSettings, jak pokazano na weblogs.asp.net/pwilson/archive/2003/04/09/5261.aspx
Saurabh Kumar
16

Wygląda na to, że tak właśnie jest. configSource musi znajdować się w tym samym folderze lub głębiej.

Państwo mogło , choć nie jestem pewien, że powinien , należy użyć dowiązania twardego NTFS. [szalony uśmiech]

Iain M. Norman
źródło
10

Visual Studio 2015

Jeśli masz ten problem z Web.Config, zaakceptowana odpowiedź jest prawidłowa, ale po prostu ją rozszerzyła, ponieważ dałem sobie twarz-dłoń:

Po dodaniu pliku .config do projektu za pomocą opcji „Dodaj jako łącze”, a następnie ustawieniu właściwości Kopiuj łącza na „Kopiuj, jeśli nowszy” lub „Zawsze kopiuj”, plik fizyczny zostanie skopiowany do folderu / bin.

Tak więc, jeśli masz sekcję konfiguracji zdefiniowaną w Web.Config w następujący sposób:

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

wtedy musisz zdefiniować powiązany element config w następujący sposób:

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

tak, że configSource wskazuje na fizyczny plik bin \ MySpecialConfig.config, a nie na łącze. Należy również zauważyć, że ścieżka jest względną ścieżką fizyczną.

Może się to wydawać absurdalnie oczywiste, ale jeśli nie zrobiłeś tego, zanim fizyczny plik nie znajduje się jeszcze w folderze \ bin, może nie kliknąć od razu.

Serexx
źródło
8

Możesz załadować konfigurację z dowolnej lokalizacji, ale nie będzie ona dostępna we właściwościach statycznych ConfigurationManager:

Configuration myConfig = ConfigurationManager.OpenExeConfiguration(path)

(Istnieje przeciążenie, które umożliwia określenie wielu plików, aby obsługiwać hierarchię domyślną / mobilną użytkownika / lokalną użytkownika).

Utrata właściwości statycznych oznacza, że ​​cały kod musi być świadomy różnych konfiguracji.

Richard
źródło
Wymaga to załadowania całego pliku konfiguracyjnego. Potrzebuję tylko, aby appSettings i connectionStrings były takie same, reszta pliku jest inna dla każdej aplikacji, więc nie rozwiązuje problemu.
Robert MacLean,
Cała konfiguracja jest i tak ładowana przez normalne (statyczne) właściwości, więc nie robi to żadnej różnicy.
Richard
Możesz także po prostu użyć własnego formatu XML i dodać jego nazwę do plików konfiguracyjnych aplikacji i przeczytać ją bezpośrednio.
Richard
5

W przypadku parametrów połączenia rzeczywiście można wskazać udostępniony plik. Jeśli udostępniony plik znajduje się w sieci UNC, wymaga uprawnień administracyjnych na komputerze, na którym będzie hostowana aplikacja.

Rozwiązanie: w pliku web.config użyj configSource, aby wskazać lokalny plik konfiguracyjny. Ze względu na ograniczenia .Net musi znajdować się na poziomie lub poniżej poziomu głównego pliku konfiguracyjnego. Po prostu wskazuję plik w samym folderze aplikacji:

<connectionStrings configSource="ConnectionStrings.config" />

W udostępnionej lokalizacji, do której użytkownik puli aplikacji ma dostęp, dodaj plik konfiguracyjny zawierający parametry połączenia współużytkowanego. Ten plik nie może zawierać żadnego kodu XML poza samą sekcją connectionStrings. Udostępniony plik ConnectionStrings.config wygląda następująco:

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

Teraz sztuczka. Utwórz łącze symboliczne systemu Windows w folderze aplikacji wskazujące na zewnętrzny, udostępniony plik konfiguracyjny. Aby to zrobić, będziesz potrzebować uprawnień administratora:

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

Właśnie przechytrzyliśmy .Net. System konfiguracji użyje ustawienia configSource, aby znaleźć parametry połączenia w pliku lokalnym o nazwie ConnectionStrings.config. Dowiązanie symboliczne wygląda jak plik do .Net, a dowiązanie symboliczne jest rozpoznawane we współdzielonym pliku konfiguracyjnym.

Ostrzeżenia: zmiany w udostępnionym pliku nie powodują automatycznego ponownego uruchomienia aplikacji w .Net. W przypadku usług IIS witrynę sieci Web lub pulę aplikacji trzeba będzie ponownie uruchomić ręcznie.

Ze względu na konieczność posiadania uprawnień administracyjnych do tworzenia dowiązania symbolicznego to podejście może nie działać dla wszystkich. Istnieją dwie powiązane alternatywy, które mogą działać, jeśli udostępniony plik znajduje się na tym samym dysku logicznym - twarde łącza i połączenia. Zobacz i tę dyskusję, aby uzyskać więcej informacji.

Scott
źródło
3

Możesz umieścić oba ustawienia w pliku machine.config i wtedy będą one dostępne dla wszystkich aplikacji na serwerze.

freggel
źródło
Jest to opcja, ale nie chcę (potrzebuję) ustawień dostępnych dla innych aplikacji na komputerze. Martwią się parametry połączenia, mają dość ogólne nazwy, które mogą kolidować z innymi aplikacjami.
Robert MacLean,
2

Najlepszym rozwiązaniem, które znalazłem, było umieszczenie „udostępnionych” plików konfiguracyjnych w plikach centralnych, a następnie użycie zdarzenia pre-build w programie Visual Studio w celu skopiowania ich do folderu względnego każdego projektu, który tego potrzebował.

Robert MacLean
źródło
2

Miałem dość problem z tym problemem, ale znalazłem tutaj dobre rozwiązanie: uruchomienie testowe z zewnętrzną konfiguracją

(Możesz nakazać przebiegowi testowemu skopiowanie plików i katalogów do katalogu uruchamiania testowego, edytując plik .testrunconfig).

Chociaż, dlaczego projekt typu testu jednostkowego może pobierać ustawienia konfiguracji z własnego pliku app.config, ale nie może załadować plików konfiguracyjnych, do których istnieją odniesienia, jak zwykły app.config, jest dla mnie trochę kłopotliwe. Nazwałbym to błędem, ponieważ można by oczekiwać, że projekt testowy app.config będzie zachowywał się tak samo, jak zachowuje się app.config aplikacji, ale tak nie jest.

marcel_g
źródło
1

Możesz użyć fileatrybutu zamiastconfigSource

Jest to dobry artykuł tutaj na nim

Pozwala to określić względną ścieżkę, taką jak ta

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

Ścieżka jest określana względem katalogu wyjściowego.

Następnie w ExternalFile.config wystarczy dodać appSettingssekcję

<appSettings>
    <add key="SomeKey" value="alue"/>
</appSettings>
Alexs
źródło