Come si modificano le appSettings web.config in fase di esecuzione?


84

Sono confuso su come modificare i valori appSettings di web.config in fase di esecuzione. Ad esempio, ho questa sezione appSettings:

<appSettings>
  <add key="productspagedesc" value="TODO: Edit this default message" />
  <add key="servicespagedesc" value="TODO: Edit this default message" />
  <add key="contactspagedesc" value="TODO: Edit this default message" />
  <add key="aboutpagedesc" value="TODO: Edit this default message" />
  <add key="homepagedesc" value="TODO: Edit this default message" />
 </appSettings>

Diciamo che voglio modificare la chiave "homepagedesc" in fase di esecuzione. Ho provato le classi statiche ConfigurationManager e WebConfigurationManager, ma le impostazioni sono di "sola lettura". Come si modificano i valori di appSettings in fase di esecuzione?

AGGIORNAMENTO: Ok, quindi eccomi qui 5 anni dopo. Vorrei sottolineare che l'esperienza mi ha detto, non dovremmo mettere alcuna configurazione che sia intenzionalmente modificabile in fase di esecuzione nel file web.config ma dovremmo invece metterla in un file XML separato come quello che uno degli utenti ha commentato di seguito. Ciò non richiederà alcuna modifica del file web.config per riavviare l'app, il che si tradurrà in utenti arrabbiati che ti chiamano.


Ecco un buon collegamento che spiega bene come modificare web.config in fase di esecuzione e il suo impatto nell'applicazione. http://aspdotnethacker.blogspot.com/2010/05/modify-webconfig-file-at-runtime.html

5
@ user330004 il link che hai fornito non è più valido
McArthey

Ci vogliono solo pochi secondi per trovare la versione archiviata !
stuartd

Risposte:


84

È necessario utilizzare WebConfigurationManager.OpenWebConfiguration(): Ad esempio:

Dim myConfiguration As Configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~")
myConfiguration.ConnectionStrings.ConnectionStrings("myDatabaseName").ConnectionString = txtConnectionString.Text
myConfiguration.AppSettings.Settings.Item("myKey").Value = txtmyKey.Text
myConfiguration.Save()

Penso che potresti anche dover impostare AllowLocation in machine.config. Si tratta di un valore booleano che indica se le singole pagine possono essere configurate utilizzando l'elemento. Se "allowLocation" è falso, non può essere configurato nei singoli elementi.

Infine, fa la differenza se esegui la tua applicazione in IIS ed esegui l'esempio di test da Visual Studio. L'identità del processo ASP.NET è l'account IIS, ASPNET o SERVIZI DI RETE (a seconda della versione di IIS).

Potrebbe essere necessario concedere ASPNET o NETWORK SERVICES Modifica l'accesso alla cartella in cui risiede web.config.


1
Grazie per la risposta Mitch. Hai risposto alla mia domanda. Quello che ho fatto è stato eseguire VS 2008 come amministratore e tutto andava bene.
jerbersoft

Forse ovvia per gli altri (non era per me), questa risposta, così come quella di Amin che è funzionalmente la stessa, in realtà sovrascrive il tuo file web.config fisico, non si limita a sovrascrivere l'impostazione in memoria per l'istanza specifica in esecuzione.
k3davis

24

La modifica di web.config provoca generalmente il riavvio dell'applicazione.

Se hai davvero bisogno che la tua applicazione modifichi le proprie impostazioni, dovresti considerare un approccio diverso come il database delle impostazioni o la creazione di un file xml con le impostazioni modificabili.


1
Ciao, grazie per la risposta. Ma c'è questa classe "Configurazione" che ha una funzione "Salva". Devi davvero riavviare l'app affinché le nuove impostazioni siano attive?
jerbersoft

4
La modifica di web.config attiva automaticamente il riavvio dell'applicazione.
Mike Cole

1
La modifica dinamica di web.config non dovrebbe essere raccomandata. Preferirei memorizzare il valore in un file (xml).
Deepak Mishra

qualcuno può spiegare perché il riavvio dell'applicazione è dannoso e molti consigliano di spostare l'attributo in un file diverso?
Ben

1
@ Ben - So che sono passati alcuni mesi, ma per ogni evenienza - riavviare l'app significherà che chiunque abbia effettuato l'accesso alla tua app al momento del riavvio verrà disconnesso automaticamente e molto probabilmente incontrerà un errore. (nonostante vari scenari come le web farm ...). utenti arrabbiati contattano il supporto, il supporto ti contatta ecc ecc ecc ...
Fetchez la vache

24

E se vuoi evitare il riavvio dell'applicazione, puoi spostare la appSettingssezione:

<appSettings configSource="Config\appSettings.config"/>

in un file separato. E in combinazione conConfigurationSaveMode.Minimal

var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
config.Save(ConfigurationSaveMode.Minimal);

è possibile continuare a utilizzare la appSettingssezione come archivio per varie impostazioni senza provocare il riavvio dell'applicazione e senza la necessità di utilizzare un file con un formato diverso rispetto alla normale sezione appSettings.


22

2012 Questa è una soluzione migliore per questo scenario (testato con Visual Studio 2008 ):

Configuration config = WebConfigurationManager.OpenWebConfiguration(HttpContext.Current.Request.ApplicationPath);
config.AppSettings.Settings.Remove("MyVariable");
config.AppSettings.Settings.Add("MyVariable", "MyValue");
config.Save();

Aggiornamento 2018 =>
Testato in vs 2015 - Asp.net MVC5

var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
config.AppSettings.Settings["MyVariable"].Value = "MyValue";
config.Save();

se hai bisogno di controllare l'esistenza dell'elemento, usa questo codice:

var config = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
if (config.AppSettings.Settings["MyVariable"] != null)
{
config.AppSettings.Settings["MyVariable"].Value = "MyValue";
}
else { config.AppSettings.Settings.Add("MyVariable", "MyValue"); }
config.Save();

Potresti spiegare un po 'perché è meglio? So che le cose di configSection a volte sono un po 'complicate.
julealgon

1
Questo codice è più piccolo e più comprensibile! Almeno per me.
Amin Ghaderi

3
Oh, è a causa del gusto personale quindi, in realtà ho pensato che fosse logicamente diverso in qualche modo. Non sono assolutamente d'accordo con te in questo caso, anche se in realtà per una serie di motivi: in primo luogo perché devi specificare la stessa chiave due volte, secondo perché ciò che stai facendo è semanticamente diverso da ciò che è effettivamente necessario ('update' vs 'remove-> aggiungi ') e terzo perché il codice è effettivamente più lungo (non sono sicuro del motivo per cui la cosa altrimenti qui) e aperto agli errori. Inoltre, cosa succede se per qualche motivo il tuo codice fallisce tra le chiamate? La tua domanda è interrotta da lì in poi credo.
julealgon

2
Questo codice cancella qualsiasi commento di pari livello a MyVariable.
blagus

Si, esattamente ! Questo codice codice deve essere riscritto tutte le variabili, ma funziona. ma non consiglio di usarlo, quando hai usato il codice di commento. Grazie.
Amin Ghaderi

14

So che questa domanda è vecchia, ma volevo pubblicare una risposta basata sullo stato attuale delle cose nel mondo ASP.NET \ IIS combinato con la mia esperienza nel mondo reale.

Di recente ho guidato un progetto presso la mia azienda in cui volevo consolidare e gestire tutte le impostazioni di appSettings e connectionStrings nei nostri file web.config in un'unica posizione centrale. Volevo perseguire un approccio in cui le nostre impostazioni di configurazione fossero memorizzate in ZooKeeper a causa della maturità e stabilità dei progetti. Per non parlare del fatto che ZooKeeper è in base alla progettazione un'applicazione per la gestione della configurazione e dei cluster.

Gli obiettivi del progetto erano molto semplici;

  1. ottenere ASP.NET per comunicare con ZooKeeper
  2. in Global.asax, Application_Start - estrae le impostazioni web.config da ZooKeeper.

Dopo aver superato la parte tecnica per convincere ASP.NET a parlare con ZooKeeper, ho rapidamente trovato e colpito un muro con il codice seguente;

ConfigurationManager.AppSettings.Add(key_name, data_value)

Questa affermazione aveva il senso più logico poiché volevo AGGIUNGERE nuove impostazioni alla raccolta appSettings. Tuttavia, come menzionato nel poster originale (e in molti altri), questa chiamata di codice restituisce un errore che indica che la raccolta è di sola lettura.

Dopo aver fatto un po 'di ricerca e visto tutti i diversi modi folli in cui le persone hanno risolto questo problema, ero molto scoraggiato. Invece di arrendermi o accontentarmi di quello che sembrava uno scenario tutt'altro che ideale, ho deciso di scavare e vedere se mi mancava qualcosa.

Con un po 'di tentativi ed errori, ho scoperto che il seguente codice avrebbe fatto esattamente quello che volevo;

ConfigurationManager.AppSettings.Set(key_name, data_value)

Utilizzando questa riga di codice, ora sono in grado di caricare tutte le 85 chiavi appSettings da ZooKeeper nel mio Application_Start.

Per quanto riguarda le dichiarazioni generali sulle modifiche a web.config che attivano i ricicli di IIS, ho modificato le seguenti impostazioni di appPool per monitorare la situazione dietro le quinte;

appPool-->Advanced Settings-->Recycling-->Disable Recycling for Configuration Changes = False
appPool-->Advanced Settings-->Recycling-->Generate Recycle Event Log Entry-->[For Each Setting] = True

Con questa combinazione di impostazioni, se questo processo dovesse causare un riciclo di appPool, dovrebbe essere registrata una voce del registro eventi, cosa che non è stata.

Questo mi porta a concludere che è possibile, e in effetti sicuro, caricare le impostazioni di un'applicazione da un supporto di memorizzazione centralizzato.

Devo dire che sto usando IIS7.5 su Windows 7. Il codice verrà distribuito su IIS8 su Win2012. Se qualcosa riguardante questa risposta cambia, aggiornerò questa risposta di conseguenza.


Questo probabilmente mi ha fatto risparmiare solo qualche ora. Grazie mille!
Drew Delano

4

A chi piace direttamente al punto,

Nella tua configurazione

    <appSettings>

    <add key="Conf_id" value="71" />

  </appSettings>

nel tuo codice (c #)

///SET
    ConfigurationManager.AppSettings.Set("Conf_id", "whateveryourvalue");
      ///GET              
    string conf = ConfigurationManager.AppSettings.Get("Conf_id").ToString();

0

Prova questo:

using System;
using System.Configuration;
using System.Web.Configuration;

namespace SampleApplication.WebConfig
{
    public partial class webConfigFile : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //Helps to open the Root level web.config file.
            Configuration webConfigApp = WebConfigurationManager.OpenWebConfiguration("~");
            //Modifying the AppKey from AppValue to AppValue1
            webConfigApp.AppSettings.Settings["ConnectionString"].Value = "ConnectionString";
            //Save the Modified settings of AppSettings.
            webConfigApp.Save();
        }
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.