¿Cómo se modifica la configuración de la aplicación web.config en tiempo de ejecución?

84

Estoy confundido sobre cómo modificar los valores de web.config appSettings en tiempo de ejecución. Por ejemplo, tengo esta sección 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>

Digamos que quiero modificar la clave "homepagedesc" en tiempo de ejecución. Probé las clases estáticas ConfigurationManager y WebConfigurationManager, pero la configuración es de "solo lectura". ¿Cómo modifico los valores de appSettings en tiempo de ejecución?

ACTUALIZACIÓN: Ok, aquí estoy 5 años después. Me gustaría señalar que la experiencia me ha dicho que no deberíamos poner ninguna configuración que sea editable intencionalmente en tiempo de ejecución en el archivo web.config, sino que deberíamos ponerla en un archivo XML separado como lo comentó uno de los usuarios a continuación. Esto no requerirá ninguna edición del archivo web.config para reiniciar la aplicación, lo que resultará en que los usuarios enojados lo llamen.

jerbersoft
fuente
Aquí hay un buen enlace que explica muy bien cómo modificar web.config en tiempo de ejecución y su impacto en la aplicación. http://aspdotnethacker.blogspot.com/2010/05/modify-webconfig-file-at-runtime.html
5
@ user330004 el enlace que proporcionó ya no es válido
McArthey
¡Solo toma unos segundos encontrar la versión archivada !
stuartd

Respuestas:

84

Necesita usar WebConfigurationManager.OpenWebConfiguration(): Por ejemplo:

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

Creo que también es posible que deba configurar AllowLocation en machine.config . Este es un valor booleano que indica si se pueden configurar páginas individuales usando el elemento. Si "allowLocation" es falso, no se puede configurar en elementos individuales.

Finalmente, hace una diferencia si ejecuta su aplicación en IIS y ejecuta su muestra de prueba desde Visual Studio. La identidad del proceso ASP.NET es la cuenta IIS, ASPNET o SERVICIOS DE RED (según la versión de IIS).

Es posible que deba otorgar ASPNET o SERVICIOS DE RED Modificar el acceso a la carpeta donde reside web.config.

Trigo Mitch
fuente
1
Gracias por la respuesta Mitch. Respondiste a mi pregunta. Lo que hice fue ejecutar VS 2008 como administrador y todo iba bien.
jerbersoft
Quizás obvio para otros (no lo era para mí), esta respuesta, así como la de Amin, que es funcionalmente la misma, en realidad sobrescribe su archivo físico web.config, no solo anula la configuración en la memoria para la instancia en ejecución específica.
k3davis
24

El cambio de web.config generalmente provoca el reinicio de la aplicación.

Si realmente necesita que su aplicación edite su propia configuración, entonces debería considerar un enfoque diferente, como basar la configuración en datos o crear un archivo xml con la configuración editable.

Joel
fuente
1
Hola, gracias por la respuesta. Pero existe esta clase de "Configuración" que tiene una función "Guardar". ¿Realmente tienes que reiniciar la aplicación para que la nueva configuración esté activa?
jerbersoft
4
Cambiar web.config activa automáticamente un reinicio de la aplicación.
Mike Cole
1
No se recomienda cambiar web.config dinámicamente. Preferiría almacenar el valor en un archivo (xml).
Deepak Mishra
¿Alguien puede explicar por qué es malo reiniciar la aplicación y muchos recomiendan mover el atributo a un archivo diferente?
Ben
1
@Ben: sé que hace unos meses, pero por si acaso, reiniciar la aplicación significará que cualquier persona que haya iniciado sesión en su aplicación en el punto de reinicio se cerrará automáticamente y probablemente encontrará un error. (a pesar de varios escenarios, como granjas web ...). usuarios de ira de contacto de apoyo, el apoyo se comunica con usted, etc, etc, etc ...
Fetchez la vache
24

Y si quieres evitar el reinicio de la aplicación, puedes salir de la appSettingssección:

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

a un archivo separado. Y en combinación conConfigurationSaveMode.Minimal

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

puede continuar usando la appSettingssección como la tienda para varias configuraciones sin que la aplicación se reinicie y sin la necesidad de usar un archivo con un formato diferente al de la sección normal de appSettings.

Ciprian Teiosanu
fuente
21

2012 Esta es una mejor solución para este escenario (probado 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();

Actualización 2018 =>
Probado en vs 2015 - Asp.net MVC5

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

Si necesita verificar que el elemento existe, use este código:

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
fuente
¿Podrías explicar un poco por qué es mejor? Sé que las cosas de configSection a veces son un poco complicadas.
julealgon
1
¡Este código es más pequeño y más comprensible! Al menos para mi.
Amin Ghaderi
3
Oh, es por gusto personal entonces, en realidad pensé que era lógicamente diferente de alguna manera. Sin embargo, estoy muy en desacuerdo contigo en este caso por un montón de razones: primero porque tienes que especificar la misma clave dos veces, segundo porque lo que estás haciendo es semánticamente diferente de lo que realmente se necesita ('actualizar' vs 'eliminar-> add ') y tercero porque el código es en realidad más largo (no estoy seguro de por qué piensa de otra manera aquí) y está abierto a errores. Además, ¿qué pasa si por alguna razón su código falla entre las llamadas? Creo que tu aplicación está rota a partir de ahí.
julealgon
2
Este código borra cualquier comentario hermano de MyVariable.
blagus
Sí exactamente ! Este código se reescribe todas las variables, pero funciona. pero no recomiendo usarlo, cuando usó código de comentario. Gracias.
Amin Ghaderi
14

Sé que esta pregunta es antigua, pero quería publicar una respuesta basada en el estado actual de las cosas en el mundo ASP.NET \ IIS combinado con mi experiencia en el mundo real.

Recientemente encabecé un proyecto en mi empresa en el que quería consolidar y administrar todas las configuraciones de appSettings y connectionStrings en nuestros archivos web.config en un lugar central. Quería seguir un enfoque en el que nuestras configuraciones de configuración se almacenaran en ZooKeeper debido a la madurez y estabilidad de los proyectos. Sin mencionar el hecho de que ZooKeeper es por diseño una aplicación de configuración y administración de clústeres.

Los objetivos del proyecto eran muy simples;

  1. obtener ASP.NET para comunicarse con ZooKeeper
  2. en Global.asax, Application_Start: extraiga la configuración web.config de ZooKeeper.

Tras aprobar la pieza técnica de hacer que ASP.NET hable con ZooKeeper, rápidamente encontré y choqué contra una pared con el siguiente código;

ConfigurationManager.AppSettings.Add(key_name, data_value)

Esa declaración tenía el sentido más lógico ya que quería AGREGAR nuevas configuraciones a la colección appSettings. Sin embargo, como mencionó el póster original (y muchos otros), esta llamada de código devuelve un error que indica que la colección es de solo lectura.

Después de investigar un poco y ver todas las diferentes formas locas en que la gente solucionó este problema, estaba muy desanimado. En lugar de rendirme o conformarme con lo que parecía ser un escenario menos que ideal, decidí indagar y ver si me estaba perdiendo algo.

Con un poco de prueba y error, encontré que el siguiente código haría exactamente lo que quería;

ConfigurationManager.AppSettings.Set(key_name, data_value)

Con esta línea de código, ahora puedo cargar las 85 claves de configuración de aplicaciones de ZooKeeper en mi Application_Start.

Con respecto a las declaraciones generales sobre los cambios en web.config que desencadenan el reciclaje de IIS, edité la siguiente configuración de appPool para monitorear la situación detrás de escena;

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

Con esa combinación de configuraciones, si este proceso provocara un reciclaje de appPool, debería haberse registrado una entrada en el Registro de eventos, lo cual no fue así.

Esto me lleva a concluir que es posible, y de hecho seguro, cargar la configuración de una aplicación desde un medio de almacenamiento centralizado.

Debo mencionar que estoy usando IIS7.5 en Windows 7. El código se implementará en IIS8 en Win2012. Si algo con respecto a esta respuesta cambia, actualizaré esta respuesta en consecuencia.

Sabio
fuente
Probablemente esto me haya ahorrado unas pocas horas. ¡Muchas gracias!
Drew Delano
4

¿A quién le gusta ir directamente al grano?

En tu configuración

    <appSettings>

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

  </appSettings>

en su código (c #)

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

Prueba esto:

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();
        }
    }
}
Antiguos alumnos de Code
fuente