Comment modifiez-vous les paramètres appSettings web.config lors de l'exécution?

84

Je ne sais pas comment modifier les valeurs appSettings de web.config lors de l'exécution. Par exemple, j'ai cette section 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>

Disons que je veux modifier la clé "homepagedesc" au moment de l'exécution. J'ai essayé les classes statiques ConfigurationManager et WebConfigurationManager, mais les paramètres sont "en lecture seule". Comment modifier les valeurs appSettings lors de l'exécution?

MISE À JOUR: Ok, donc me voici 5 ans plus tard. Je tiens à souligner que l'expérience m'a dit, nous ne devrions pas mettre de configuration qui est intentionnellement modifiable au moment de l'exécution dans le fichier web.config, mais au lieu de cela, nous devrions le mettre dans un fichier XML séparé comme ce que l'un des utilisateurs a commenté ci-dessous. Cela ne nécessitera aucune modification du fichier web.config pour redémarrer l'application, ce qui entraînera des utilisateurs en colère qui vous appelleront.

Jerbersoft
la source
Voici un bon lien qui explique bien comment modifier le web.config au moment de l'exécution et son impact dans l'application. http://aspdotnethacker.blogspot.com/2010/05/modify-webconfig-file-at-runtime.html
5
@ user330004 le lien que vous avez fourni n'est plus valide
McArthey
La recherche de la version archivée ne prend que quelques secondes !
stuartd

Réponses:

84

Vous devez utiliser WebConfigurationManager.OpenWebConfiguration(): Par exemple:

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

Je pense que vous devrez peut-être également définir AllowLocation dans machine.config. Il s'agit d'une valeur booléenne qui indique si des pages individuelles peuvent être configurées à l'aide de l'élément. Si "allowLocation" est faux, il ne peut pas être configuré dans des éléments individuels.

Enfin, cela fait une différence si vous exécutez votre application dans IIS et exécutez votre exemple de test à partir de Visual Studio. L'identité du processus ASP.NET est le compte IIS, ASPNET ou NETWORK SERVICES (selon la version IIS).

Il se peut que vous deviez accorder un accès à ASPNET ou à NETWORK SERVICES Modifier sur le dossier où réside web.config.

Blé Mitch
la source
1
Merci pour la réponse Mitch. Vous avez répondu à ma question. Ce que j'ai fait, c'est que j'ai lancé VS 2008 en tant qu'administrateur et tout allait bien.
jerbersoft
Peut-être évident pour les autres (ce n'était pas pour moi), cette réponse, ainsi que celle d'Amin qui est fonctionnellement la même, écrase en fait votre fichier web.config physique, ne remplace pas seulement le paramètre en mémoire pour l'instance en cours d'exécution spécifique.
k3davis
24

La modification du fichier web.config entraîne généralement un redémarrage de l'application.

Si vous avez vraiment besoin que votre application modifie ses propres paramètres, vous devez envisager une approche différente, telle que la base de données des paramètres ou la création d'un fichier xml avec les paramètres modifiables.

Joël
la source
1
Salut, merci pour la réponse. Mais il y a cette classe "Configuration" qui a une fonction "Enregistrer". Devez-vous vraiment redémarrer l'application pour que les nouveaux paramètres soient actifs?
jerbersoft
4
La modification du fichier web.config déclenche automatiquement un redémarrage de l'application.
Mike Cole
1
La modification dynamique de web.config ne doit pas être recommandée. Je préférerais stocker la valeur dans un fichier (xml).
Deepak Mishra
quelqu'un peut-il expliquer pourquoi le redémarrage de l'application est mauvais et beaucoup recommandent de déplacer l'attribut vers un autre fichier?
Ben le
1
@Ben - Je sais que cela fait quelques mois, mais juste au cas où - le redémarrage de l'application signifiera que toute personne connectée à votre application au moment du redémarrage sera automatiquement déconnectée et rencontrera très probablement une erreur. (divers scénarios tels que les fermes Web nonobstant ...). les utilisateurs en colère contactent le support, vous contactent, etc. etc etc ...
Fetchez la vache
24

Et si vous souhaitez éviter le redémarrage de l'application, vous pouvez sortir de la appSettingssection:

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

dans un fichier séparé. Et en combinaison avecConfigurationSaveMode.Minimal

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

vous pouvez continuer à utiliser la appSettingssection comme magasin pour divers paramètres sans provoquer le redémarrage de l'application et sans avoir besoin d'utiliser un fichier avec un format différent de la section normale appSettings.

Ciprian Teiosanu
la source
21

2012 Il s'agit d'une meilleure solution pour ce scénario (testé avec Visual Studio 2008 ):

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

Mise à jour 2018 =>
Testé en vs 2015 - Asp.net MVC5

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

si vous avez besoin de vérifier l'existence d'un élément, utilisez ce 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
la source
Pourriez-vous expliquer un peu pourquoi c'est mieux? Je sais que les trucs de configSection sont parfois un peu délicats.
julealgon
1
Ce code est plus petit et plus compréhensible! Au moins pour moi.
Amin Ghaderi
3
Oh, c'est à cause de goût personnel alors, je pensais en fait que c'était logiquement différent en quelque sorte. Je ne suis pas du tout d'accord avec vous dans ce cas pour un tas de raisons en fait: d'abord parce que vous devez spécifier la même clé deux fois, ensuite parce que ce que vous faites est sémantiquement différent de ce qui est réellement nécessaire ('update' vs 'remove-> add ') et troisièmement parce que le code est en fait plus long (je ne sais pas pourquoi vous pensez autrement ici) et ouvert aux erreurs. Et si, pour une raison quelconque, votre code échoue entre les appels? Votre application est interrompue à partir de là, je pense.
julealgon
2
Ce code efface tout commentaire frère de MyVariable.
blagus
Oui, exactement ! Ce code code être réécrit toutes les variables, mais cela fonctionne. mais je ne recommande pas de l'utiliser, lorsque vous avez utilisé le code de commentaire. Merci.
Amin Ghaderi
14

Je sais que cette question est ancienne, mais je voulais publier une réponse basée sur l'état actuel des choses dans le monde ASP.NET \ IIS combiné à mon expérience du monde réel.

J'ai récemment dirigé un projet dans mon entreprise dans lequel je voulais consolider et gérer tous les paramètres appSettings & connectionStrings dans nos fichiers web.config en un seul endroit central. Je voulais poursuivre une approche où nos paramètres de configuration étaient stockés dans ZooKeeper en raison de la maturité et de la stabilité des projets. Sans oublier que ZooKeeper est par conception une application de gestion de configuration et de cluster.

Les objectifs du projet étaient très simples;

  1. obtenir ASP.NET pour communiquer avec ZooKeeper
  2. dans Global.asax, Application_Start - tirez les paramètres web.config de ZooKeeper.

Après avoir passé la partie technique pour obtenir ASP.NET pour parler à ZooKeeper, j'ai rapidement trouvé et frappé un mur avec le code suivant;

ConfigurationManager.AppSettings.Add(key_name, data_value)

Cette déclaration avait le sens le plus logique puisque je voulais AJOUTER de nouveaux paramètres à la collection appSettings. Cependant, comme l'affiche d'origine (et bien d'autres) l'a mentionné, cet appel de code renvoie une erreur indiquant que la collection est en lecture seule.

Après avoir fait un peu de recherche et vu toutes les différentes façons folles dont les gens travaillaient autour de ce problème, j'étais très découragée. Au lieu d'abandonner ou de me contenter de ce qui semblait être un scénario loin d'être idéal, j'ai décidé de creuser et de voir si je manquais quelque chose.

Avec un peu d'essais et d'erreurs, j'ai trouvé que le code suivant ferait exactement ce que je voulais;

ConfigurationManager.AppSettings.Set(key_name, data_value)

En utilisant cette ligne de code, je suis maintenant en mesure de charger les 85 clés appSettings de ZooKeeper dans mon Application_Start.

En ce qui concerne les déclarations générales sur les modifications apportées à web.config déclenchant le recyclage d'IIS, j'ai modifié les paramètres appPool suivants pour surveiller la situation dans les coulisses;

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

Avec cette combinaison de paramètres, si ce processus devait provoquer un recyclage appPool, une entrée du journal des événements aurait dû être enregistrée, ce qui n'était pas le cas.

Cela m'amène à conclure qu'il est possible, et en fait sûr, de charger les paramètres d'une application à partir d'un support de stockage centralisé.

Je dois mentionner que j'utilise IIS7.5 sur Windows 7. Le code sera déployé sur IIS8 sur Win2012. En cas de changement concernant cette réponse, je mettrai à jour cette réponse en conséquence.

sauge
la source
Cela m'a probablement fait gagner quelques heures. Merci beaucoup!
Drew Delano le
4

Qui aime directement au point,

Dans votre configuration

    <appSettings>

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

  </appSettings>

dans votre code (c #)

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

Essaye ça:

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();
        }
    }
}
Anciens du Code
la source