.NET-Konfigurationsdateien configSource außerhalb des Anwendungsverzeichnisordners

81

Ich habe zwei Anwendungen, eine Konsolenanwendung und eine ASP.NET-Anwendung. Beide müssen dieselben AppSettings und ConnectionStrings kennen. Idealerweise möchte ich die configSource-Eigenschaft von app.config / web.config-Dateien verwenden, um dies auf einen zentralen Speicherort zu verweisen. Beispielsweise

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

Das scheitert jedoch mit einem Fehler:

Das configSource-Attribut ist ungültig: Die configSource 'D: \ appSettings.config' ist ungültig. Es muss sich auf eine Datei im selben Verzeichnis oder in einem Unterverzeichnis wie die Konfigurationsdatei beziehen.

Gibt es überhaupt noch die Konfigurationsmanager appSettings / connectionStrings zu verwenden und die Werte von einem externen Speicherort abzurufen?
Ich bin froh, dass ich dafür Code hinzufügen muss, aber ich möchte nicht das gesamte Konfigurationsmanagersystem ersetzen müssen.

Robert MacLean
quelle

Antworten:

101

Eine andere Lösung besteht einfach darin, die Konfigurationsdatei in all Ihren Projekten als Link hinzuzufügen, anstatt die Datei tatsächlich in Ihre Projekte zu kopieren. Setzen Sie dann die "Build-Aktion" der Datei auf "Inhalt" und "In Ausgabeverzeichnis kopieren" auf "Wenn neuer kopieren". Wenn Sie das Projekt kompilieren, befindet sich die Datei im Ausgabeverzeichnis.

Um die Datei als Link im Dialogfeld "Vorhandenes Element hinzufügen" hinzuzufügen, gibt es eine Schaltfläche Hinzufügen mit einer Dropdown-Liste. Wählen Sie "Als Link hinzufügen" aus der Dropdown-Liste auf der Schaltfläche "Hinzufügen", um den Vorgang abzuschließen.

Gemeinschaft
quelle
nett - viel einfacher für die Leute zu verstehen als mein Weg
Robert MacLean
10
Hallo, ich mag diese Antwort und habe versucht, sie auf mein eigenes Projekt anzuwenden, und alles scheint gut zu funktionieren, wenn ich meine App "veröffentliche" (db.config wird wie gesagt auf die Webroot kopiert), aber nicht beim Debuggen über VS & Cassini. Stattdessen erhalte ich die Ausnahme "Die configSource-Datei 'db.config' kann nicht geöffnet werden". Fehlt mir etwas, um dies tun zu können? Vielen Dank!
Funka
16
Natürlich finde ich es erst gleich nach meiner Entscheidung, zusammenzubrechen und einen Kommentar zu schreiben und um Hilfe zu bitten, gleich danach heraus. Ich habe festgestellt, dass meine Datei db.config auch in den Ordner / bin / kopiert wurde. Daher habe ich meine Datei web.config aktualisiert, um diesen Pfad in seiner Reihenfolge voranzustellen, configSourceund alles scheint in Ordnung zu sein . Danke noch einmal!
Funka
1
@Funka - Überprüfen Sie, ob das Problem auftritt, da die Eigenschaft "Build Action" Ihrer db.config wie die Standard-web.config auf "None" anstelle von "Content" gesetzt ist. Ich glaube, die Einstellungen sollten "Build Action" = "Content" und "Copy to Output Directory" = "Don't copy" sein.
bopapa_1979
1
Dies scheint beim Debuggen in VS 2013 nicht zu funktionieren. Ich habe die Erics-Lösung ausprobiert und dies hat auch nicht funktioniert.
Chris Nevill
34

Unter appSettings können Sie file = anstelle von configSource = verwenden


quelle
1
Hervorragender Fund für mich! Vielen Dank!! Damit kann ich ausgewählte Schlüssel in AppSettings überschreiben, wie unter weblogs.asp.net/pwilson/archive/2003/04/09/5261.aspx
Saurabh Kumar
16

Es scheint so zu sein. configSource muss sich im selben Ordner oder tiefer befinden.

Sie können , obwohl ich nicht sicher bin, ob Sie dies tun sollten , einen NTFS-Hardlink verwenden. [verrücktes Grinsen]

Iain M Norman
quelle
9

Visual Studio 2015

Wenn Sie dieses Problem mit Web.Config haben, ist die akzeptierte Antwort korrekt, aber nur zur Erweiterung, da ich mir die Gesichtspalme gegeben habe:

Wenn Sie Ihrem Projekt mit 'Als Link hinzufügen' eine .config-Datei hinzufügen und dann die Copy-Eigenschaft des Links auf 'Copy If Newer' oder 'Copy Always' setzen, wird die physische Datei in den Ordner / bin kopiert.

Wenn Sie also einen Konfigurationsabschnitt wie folgt in Web.Config definiert haben:

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

dann müssen Sie das zugehörige Konfigurationselement wie folgt definieren:

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

So dass die configSource auf die physische Datei bin \ MySpecialConfig.config verweist und nicht auf den Link . Beachten Sie außerdem, dass der Pfad ein relativer physischer Pfad ist.

Das mag lächerlich offensichtlich erscheinen, aber wenn Sie dies noch nicht getan haben, befindet sich die physische Datei noch nicht im Ordner \ bin, sodass sie möglicherweise nicht sofort klickt.

Serexx
quelle
8

Sie können Konfiguration von einem beliebigen Ort laden, aber es wird nicht über die statischen Eigenschaften von Konfigurationsmanager zur Verfügung stehen:

Configuration myConfig = ConfigurationManager.OpenExeConfiguration(path)

(Es gibt eine Überlastung, mit der mehrere Dateien angegeben werden können, um die Standardhierarchie / Benutzerroaming / Benutzerlokale Hierarchie zu unterstützen.)

Der Verlust der statischen Eigenschaften bedeutet, dass der gesamte Code die unterschiedliche Konfiguration kennen muss.

Richard
quelle
Dies erfordert, dass die gesamte Konfigurationsdatei geladen wird. Ich brauche nur, dass die appSettings & connectionStrings gleich sind. Der Rest der Datei ist für jede App unterschiedlich, sodass das Problem nicht gelöst wird.
Robert MacLean
Die gesamte Konfiguration wird ohnehin durch die normalen (statischen) Eigenschaften geladen, sodass dies keinen wirklichen Unterschied macht.
Richard
Sie können auch einfach Ihr eigenes XML-Format verwenden und seinen Namen zu den Konfigurationsdateien der Anwendungen hinzufügen und direkt lesen.
Richard
4

Bei Verbindungszeichenfolgen ist es tatsächlich möglich, auf eine gemeinsam genutzte Datei zu verweisen. Wenn sich die freigegebene Datei in einem Netzwerk-UNC befindet, sind Administratorrechte auf dem Computer erforderlich, auf dem die App gehostet wird.

Lösung: Verwenden Sie in Ihrer web.config configSource, um auf eine lokale Konfigurationsdatei zu verweisen. Aufgrund von .Net-Einschränkungen muss dies auf oder unter der Ebene der Root-Konfigurationsdatei liegen. Ich zeige nur auf eine Datei im App-Ordner selbst:

<connectionStrings configSource="ConnectionStrings.config" />

Fügen Sie an einem freigegebenen Speicherort, auf den der Benutzer des Anwendungspools zugreifen kann, die Konfigurationsdatei mit freigegebenen Verbindungszeichenfolgen hinzu. Diese Datei darf keine andere XML-Datei als den Abschnitt connectionStrings selbst enthalten. Die freigegebene Datei ConnectionStrings.config sieht folgendermaßen aus:

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

Nun der Trick. Erstellen Sie in Ihrem App-Ordner einen symbolischen Windows-Link, der auf die externe, freigegebene Konfigurationsdatei verweist. Dazu benötigen Sie Administratorrechte:

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

Wir haben gerade .Net überlistet. Das Konfigurationssystem verwendet die Einstellung configSource, um Verbindungszeichenfolgen in einer lokalen Datei mit dem Namen ConnectionStrings.config zu finden. Die symbolische Verknüpfung sieht für .Net wie eine Datei aus, und die symbolische Verknüpfung wird in die freigegebene Konfigurationsdatei aufgelöst.

Vorsichtsmaßnahmen: Änderungen an der freigegebenen Datei lösen nicht automatisch einen Neustart der App in .Net aus. Bei IIS muss die Website oder der App-Pool manuell neu gestartet werden.

Aufgrund der Notwendigkeit von Administratorrechten zum Erstellen der symbolischen Verknüpfung funktioniert dieser Ansatz möglicherweise nicht für alle. Es gibt zwei verwandte Alternativen, die möglicherweise funktionieren, wenn sich die freigegebene Datei auf demselben logischen Laufwerk befindet - Hardlinks und Junctions. Weitere Informationen finden Sie in dieser Diskussion und in dieser Diskussion .

Scott
quelle
3

Sie können beide Einstellungen in die machine.config einfügen und sie sind dann für alle Ihre Anwendungen auf dem Server verfügbar.

freggel
quelle
Es ist eine Option, aber ich möchte (brauche) nicht die Einstellungen, die für andere Anwendungen auf dem Computer verfügbar sind. Sorge sind die Verbindungszeichenfolgen, sie haben ziemlich generische Namen, die mit anderen Anwendungen in Konflikt stehen können.
Robert MacLean
2

Die Lösung, die ich am besten fand, bestand darin, die "freigegebenen" Konfigurationsdateien in zentralen Dateien abzulegen und sie dann mithilfe eines Pre-Build-Ereignisses in Visual Studio in einen relativen Ordner jedes Projekts zu kopieren, das sie benötigte.

Robert MacLean
quelle
2

Ich hatte einige Probleme mit diesem Problem, aber ich habe hier eine gute Lösung dafür gefunden: Testlauf mit externer Konfiguration

(Sie können den Testlauf anweisen, Dateien und Verzeichnisse in das Testlaufverzeichnis zu kopieren, indem Sie die Datei .testrunconfig bearbeiten.)

Obwohl es für mich verwirrend ist, warum das Unit-Test-Projekt Konfigurationseinstellungen von seiner eigenen app.config abrufen kann, aber nicht in der Lage ist, referenzierte Konfigurationsdateien wie eine normale app.config zu laden. Ich würde es als Fehler bezeichnen, da Sie erwarten würden, dass sich ein Testprojekt app.config genauso verhält wie die app.config der Anwendung, dies jedoch nicht.

marcel_g
quelle
1

Sie können das fileAttribut anstelle von verwendenconfigSource

Es gibt einen guten Artikel hier drauf

Auf diese Weise können Sie einen relativen Pfad wie diesen angeben

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

Der Pfad ist relativ zum Ausgabeverzeichnis.

Dann fügen Sie in ExternalFile.config einfach den appSettingsAbschnitt hinzu

<appSettings>
    <add key="SomeKey" value="alue"/>
</appSettings>
alexs
quelle