Wie ändern Sie die web.config appSettings zur Laufzeit?

84

Ich bin verwirrt darüber, wie die appSettings-Werte von web.config zur Laufzeit geändert werden. Zum Beispiel habe ich diesen Abschnitt 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>

Angenommen, ich möchte den Schlüssel "homepagedesc" zur Laufzeit ändern. Ich habe statische Klassen ConfigurationManager und WebConfigurationManager ausprobiert, aber die Einstellungen sind "schreibgeschützt". Wie ändere ich appSettings-Werte zur Laufzeit?

UPDATE: Ok, also hier bin ich 5 Jahre später. Ich möchte darauf hinweisen, dass die Erfahrung mir gezeigt hat, dass wir keine Konfiguration, die absichtlich zur Laufzeit bearbeitet werden kann, in die Datei web.config einfügen sollten, sondern sie in eine separate XML-Datei einfügen sollten, wie einer der Benutzer unten kommentiert hat. Dies erfordert keine Bearbeitung der Datei web.config, um die App neu zu starten, was dazu führt, dass verärgerte Benutzer Sie anrufen.

jerbersoft
quelle
Hier ist ein guter Link, der die Änderung der web.config zur Laufzeit und ihre Auswirkungen auf die Anwendung ausführlich erläutert. http://aspdotnethacker.blogspot.com/2010/05/modify-webconfig-file-at-runtime.html
5
@ user330004 der von Ihnen angegebene Link ist nicht mehr gültig
McArthey
Das Auffinden der archivierten Version dauert nur wenige Sekunden !
stuartd

Antworten:

84

Sie müssen Folgendes verwenden WebConfigurationManager.OpenWebConfiguration(): Zum Beispiel:

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()

Ich denke, Sie müssen möglicherweise auch AllowLocation in machine.config festlegen. Dies ist ein boolescher Wert, der angibt, ob einzelne Seiten mit dem Element konfiguriert werden können. Wenn "allowLocation" false ist, kann es nicht in einzelnen Elementen konfiguriert werden.

Schließlich macht es einen Unterschied, ob Sie Ihre Anwendung in IIS ausführen und Ihr Testbeispiel in Visual Studio ausführen. Die ASP.NET-Prozessidentität ist das IIS-Konto, ASPNET oder NETWORK SERVICES (abhängig von der IIS-Version).

Möglicherweise müssen Sie ASPNET- oder NETZWERKDIENSTLEISTUNGEN gewähren. Ändern Sie den Zugriff auf den Ordner, in dem sich web.config befindet.

Mitch Wheat
quelle
1
Danke für die Antwort Mitch. Du hast meine Frage beantwortet. Ich habe VS 2008 als Administrator ausgeführt und alles lief gut.
Jerbersoft
Vielleicht für andere offensichtlich (war für mich nicht offensichtlich), überschreibt diese Antwort sowie Amins, die funktional dieselbe ist, tatsächlich Ihre physische web.config-Datei und überschreibt nicht nur die Speichereinstellung für die bestimmte laufende Instanz.
k3davis
24

Das Ändern der web.config führt im Allgemeinen zu einem Neustart der Anwendung.

Wenn Sie wirklich benötigen, dass Ihre Anwendung ihre eigenen Einstellungen bearbeitet, sollten Sie einen anderen Ansatz in Betracht ziehen, z. B. die Datenbank der Einstellungen oder das Erstellen einer XML-Datei mit den bearbeitbaren Einstellungen.

Joel
quelle
1
Hallo, danke für die Antwort. Es gibt jedoch diese "Konfigurations" -Klasse mit der Funktion "Speichern". Müssen Sie die App wirklich neu starten, damit die neuen Einstellungen aktiv sind?
Jerbersoft
4
Das Ändern der Datei web.config löst automatisch einen Neustart der Anwendung aus.
Mike Cole
1
Das dynamische Ändern von web.config sollte nicht empfohlen werden. Ich würde es vorziehen, den Wert in einer (XML-) Datei zu speichern.
Deepak Mishra
Kann jemand erklären, warum ein Neustart der Anwendung schlecht ist und viele empfehlen, das Attribut in eine andere Datei zu verschieben?
Ben
1
@Ben - Ich weiß, dass es einige Monate her ist, aber nur für den Fall - ein Neustart der App bedeutet, dass jeder, der sich zum Zeitpunkt des Neustarts bei Ihrer App angemeldet hat, automatisch abgemeldet wird und höchstwahrscheinlich auf einen Fehler stößt. (ungeachtet verschiedener Szenarien wie Webfarmen ...). verärgerte Benutzer kontaktieren Support, Support-Kontakte Sie etc etc etc ...
Fetchez la vache
24

Wenn Sie den Neustart der Anwendung vermeiden möchten, können Sie den appSettingsAbschnitt verschieben:

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

in eine separate Datei. Und in Kombination mitConfigurationSaveMode.Minimal

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

Sie können den appSettingsAbschnitt weiterhin als Speicher für verschiedene Einstellungen verwenden, ohne dass die Anwendung neu gestartet wird und ohne dass eine Datei mit einem anderen Format als dem normalen Abschnitt "appSettings" verwendet werden muss.

Ciprian Teiosanu
quelle
21

2012 Dies ist eine bessere Lösung für dieses Szenario (getestet mit Visual Studio 2008 ):

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

Update 2018 =>
Getestet in vs 2015 - Asp.net MVC5

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

Wenn Sie überprüfen müssen, ob ein Element vorhanden ist, verwenden Sie diesen Code:

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();
Amin Ghaderi
quelle
Könnten Sie etwas näher erläutern, warum es besser ist? Ich weiß, dass configSection-Sachen manchmal etwas knifflig sind.
Julealgon
1
Dieser Code ist kleiner und verständlicher! Zumindest für mich.
Amin Ghaderi
3
Oh, das liegt am persönlichen Geschmack, ich dachte tatsächlich, dass es irgendwie logisch anders ist. In diesem Fall stimme ich Ihnen jedoch aus einer Reihe von Gründen nicht zu: Erstens, weil Sie denselben Schlüssel zweimal angeben müssen, zweitens, weil sich das, was Sie tun, semantisch von dem unterscheidet, was tatsächlich benötigt wird ('update' vs 'remove-> add ') und drittens, weil der Code tatsächlich länger ist (nicht sicher, warum Sie hier etwas anderes tun) und offen für Fehler ist. Was ist auch, wenn Ihr Code aus irgendeinem Grund zwischen den Aufrufen fehlschlägt? Ihre Bewerbung ist von da an kaputt, denke ich.
Julealgon
2
Dieser Code löscht alle Kommentare zu MyVariable.
Blagus
Ja genau ! Dieser Code Code wird alle Variablen neu geschrieben, aber es funktioniert. aber ich empfehle nicht, es zu verwenden, wenn Sie Kommentar-Code verwendet. Danke dir.
Amin Ghaderi
13

Ich weiß, dass diese Frage alt ist, aber ich wollte eine Antwort veröffentlichen, die auf dem aktuellen Stand der Dinge in der ASP.NET \ IIS-Welt in Kombination mit meiner realen Erfahrung basiert.

Ich habe kürzlich ein Projekt in meinem Unternehmen geleitet, in dem ich alle Einstellungen für appSettings & connectionStrings in unseren web.config-Dateien an einem zentralen Ort konsolidieren und verwalten wollte. Ich wollte einen Ansatz verfolgen, bei dem unsere Konfigurationseinstellungen aufgrund der Reife und Stabilität des Projekts in ZooKeeper gespeichert wurden. Ganz zu schweigen von der Tatsache, dass ZooKeeper eine Konfigurations- und Clusterverwaltungsanwendung ist.

Die Projektziele waren sehr einfach;

  1. Lassen Sie ASP.NET mit ZooKeeper kommunizieren
  2. In Global.asax, Application_Start - ziehen Sie die Einstellungen für web.config aus ZooKeeper.

Nachdem ich die technische Aufgabe erhalten hatte, ASP.NET dazu zu bringen, mit ZooKeeper zu sprechen, fand ich schnell eine Wand mit dem folgenden Code und traf sie.

ConfigurationManager.AppSettings.Add(key_name, data_value)

Diese Aussage war am logischsten, da ich der appSettings-Sammlung neue Einstellungen hinzufügen wollte. Wie im Originalposter (und vielen anderen) erwähnt, gibt dieser Codeaufruf jedoch einen Fehler zurück, der besagt, dass die Sammlung schreibgeschützt ist.

Nachdem ich ein bisschen recherchiert und all die verschiedenen verrückten Arten gesehen hatte, wie Menschen dieses Problem umgingen, war ich sehr entmutigt. Anstatt aufzugeben oder mich mit einem weniger als idealen Szenario zufrieden zu geben, beschloss ich, mich zu vertiefen und zu sehen, ob mir etwas fehlte.

Mit ein wenig Versuch und Irrtum stellte ich fest, dass der folgende Code genau das tun würde, was ich wollte;

ConfigurationManager.AppSettings.Set(key_name, data_value)

Mit dieser Codezeile kann ich jetzt alle 85 appSettings-Schlüssel von ZooKeeper in meinen Application_Start laden.

In Bezug auf allgemeine Aussagen zu Änderungen an web.config, die IIS-Recycling auslösen, habe ich die folgenden appPool-Einstellungen bearbeitet, um die Situation hinter den Kulissen zu überwachen.

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

Wenn dieser Prozess mit dieser Kombination von Einstellungen einen AppPool-Recycling verursachen sollte, sollte ein Ereignisprotokolleintrag aufgezeichnet worden sein, was nicht der Fall war.

Dies lässt mich zu dem Schluss kommen, dass es möglich und tatsächlich sicher ist, Anwendungseinstellungen von einem zentralen Speichermedium zu laden.

Ich sollte erwähnen, dass ich IIS7.5 unter Windows 7 verwende. Der Code wird unter Win2012 auf IIS8 bereitgestellt. Sollte sich etwas in Bezug auf diese Antwort ändern, werde ich diese Antwort entsprechend aktualisieren.

Salbei
quelle
Das hat mir wahrscheinlich nur ein paar Stunden gespart. Vielen Dank!
Drew Delano
4

Wer mag direkt auf den Punkt,

In Ihrer Konfiguration

    <appSettings>

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

  </appSettings>

in Ihrem Code (c #)

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

Versuche dies:

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();
        }
    }
}
Code Alumni
quelle