Utilizzo di ConfigurationManager per caricare la configurazione da una posizione arbitraria

StackOverflow https://stackoverflow.com/questions/4738

Domanda

Sto sviluppando un componente di accesso ai dati che verrà utilizzato in un sito Web che contiene un mix di pagine ASP e ASP.NET classiche e necessito di un buon modo per gestirne le impostazioni di configurazione.

Vorrei usare un'abitudine ConfigurationSection, e per le pagine ASP.NET funziona benissimo.Ma quando il componente viene chiamato tramite interoperabilità COM da una pagina ASP classica, il componente non viene eseguito nel contesto di una richiesta ASP.NET e pertanto non conosce web.config.

C'è un modo per dirlo ConfigurationManager per caricare semplicemente la configurazione da un percorso arbitrario (ad es. ..\web.config se la mia assemblea è nel /bin cartella)?Se c'è, allora penso che il mio componente possa ricorrere a quello predefinito ConfigurationManager.GetSection ritorna null per la mia sezione personalizzata.

Qualsiasi altro approccio a questo sarebbe il benvenuto!

È stato utile?

Soluzione

Prova questo:

System.Configuration.ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath); //Path to your config file
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedMachineConfiguration(fileMap);

Altri suggerimenti

Un'altra soluzione consiste nell'override del percorso del file di configurazione dell'ambiente predefinito.

Trovo che sia la soluzione migliore per il caricamento del file di configurazione con percorso non banale, in particolare il modo migliore per allegare il file di configurazione alla DLL.

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", <Full_Path_To_The_Configuration_File>);

Esempio:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", @"C:\Shared\app.config");

Maggiori dettagli possono essere trovati su questo blog.

Inoltre, quest'altra risposta ha una soluzione eccellente, completa di codice per aggiornare la configurazione dell'app e un IDisposable oggetto per ripristinarlo al suo stato originale.Con questa soluzione, è possibile conservare la configurazione di app temporanea con ambito:

using(AppConfig.Change(tempFileName))
{
    // tempFileName is used for the app config during this context
}

La risposta di Ishmaeel generalmente funziona, tuttavia ho riscontrato un problema, ovvero l'utilizzo OpenMappedMachineConfiguration sembra perdere i gruppi di sezioni ereditati da machine.config.Ciò significa che puoi accedere alle tue sezioni personalizzate (che è tutto ciò che l'OP desidera), ma non alle normali sezioni di sistema.Ad esempio, questo codice non funzionerà:

ConfigurationFileMap fileMap = new ConfigurationFileMap(strConfigPath);
Configuration configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns null

Fondamentalmente, se metti un orologio sul configuration.SectionGroups, vedrai che system.net non è registrato come SezioneGroup, quindi è praticamente inaccessibile tramite i normali canali.

Ci sono due modi che ho trovato per aggirare questo problema.Il primo, che non mi piace, è reimplementare i gruppi di sezioni di sistema copiandoli da machine.config nel tuo web.config, ad es.

<sectionGroup name="system.net" type="System.Net.Configuration.NetSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
  <sectionGroup name="mailSettings" type="System.Net.Configuration.MailSettingsSectionGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <section name="smtp" type="System.Net.Configuration.SmtpSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </sectionGroup>
</sectionGroup>

Non sono sicuro che l'applicazione web stessa funzionerà correttamente dopo, ma puoi accedere correttamente alla sezione Gruppi.

La seconda soluzione è invece aprire il tuo web.config come configurazione EXE, che probabilmente è comunque più vicina alla sua funzione prevista:

ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = strConfigPath };
Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
MailSettingsSectionGroup thisMail = configuration.GetSectionGroup("system.net/mailSettings") as MailSettingsSectionGroup;  // returns valid object!

Oserei dire che nessuna delle risposte fornite qui, né la mia né quella di Ishmaeel, utilizzano queste funzioni come intendevano i progettisti .NET.Ma questo sembra funzionare per me.

Oltre alla risposta di Ishmaeel, il metodo OpenMappedMachineConfiguration() restituirà sempre a Configuration oggetto.Quindi per verificare se è stato caricato dovresti controllare il file HasFile proprietà dove true significa che proviene da un file.

Ho fornito i valori di configurazione al componente .nET ospitato da Word come segue.

Un componente della libreria di classi .NET chiamato/ospitato in MS Word.Per fornire valori di configurazione al mio componente, ho creato winword.exe.config nella cartella C:\Programmi\Microsoft Office\OFFICE11.Dovresti essere in grado di leggere i valori di configurazione come fai in .NET tradizionale.

string sMsg = System.Configuration.ConfigurationManager.AppSettings["WSURL"];

La risposta accettata è sbagliata!!

Genera la seguente eccezione quando si accede alla proprietà AppSettings:

Impossibile eseguire il cast dell'oggetto di tipo "System.Configuration.DefaultSection" nel tipo "System.Configuration.AppSettingsSection".

Ecco la soluzione corretta:

System.Configuration.ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = "YourFilePath";
System.Configuration.Configuration configuration = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

Per ASP.NET utilizzare WebConfigurationManager:

var config = WebConfigurationManager.OpenWebConfiguration("~/Sites/" + requestDomain + "/");
(..)
config.AppSettings.Settings["xxxx"].Value;

Utilizza l'elaborazione XML:

var appPath = AppDomain.CurrentDomain.BaseDirectory;
var configPath = Path.Combine(appPath, baseFileName);;
var root = XElement.Load(configPath);

// can call root.Elements(...)

Questo dovrebbe fare al caso tuo:

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "newAppConfig.config);

Fonte : https://www.codeproject.com/Articles/616065/Perché-Where-and-How-of-NET-Configuration-Files

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top