Як ви змінюєте параметри web.config appSettings під час виконання?


84

Мене бентежить, як змінювати значення web.config appSettings під час виконання. Наприклад, у мене є цей розділ 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>

Скажімо, я хочу змінити ключ "homepagedesc" під час виконання. Я спробував статичні класи ConfigurationManager та WebConfigurationManager, але налаштування "лише для читання". Як змінити значення appSettings під час виконання?

ОНОВЛЕННЯ: Гаразд, отже, ось я через 5 років. Я хотів би зазначити, що досвід мені підказував, ми не повинні розміщувати будь-яку конфігурацію, яку навмисно можна редагувати під час виконання, у файлі web.config, а замість цього ми повинні помістити її в окремий файл XML, як прокоментував один із користувачів нижче. Для цього не потрібно буде редагувати файл web.config для перезапуску програми, що призведе до роздратованих користувачів, які зателефонують вам.


Ось гарне посилання, яке чудово пояснює зміну web.config під час виконання та його вплив на застосування. http://aspdotnethacker.blogspot.com/2010/05/modify-webconfig-file-at-runtime.html

5
@ user330004 надане вами посилання більше не дійсне
McArthey

Знайдіть заархівовану версію лише кілька секунд !
stuartd

Відповіді:


84

Вам потрібно використовувати WebConfigurationManager.OpenWebConfiguration(): Наприклад:

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

Я думаю, вам також може знадобитися встановити AllowLocation в machine.config. Це логічне значення, яке вказує, чи можна налаштувати окремі сторінки за допомогою елемента. Якщо параметр "allowLocation" хибний, його не можна налаштувати в окремих елементах.

Нарешті, важливо, якщо ви запускаєте програму в IIS і запускаєте тестовий зразок із Visual Studio. Ідентичність процесу ASP.NET - це обліковий запис IIS, ASPNET або МЕРЕЖНІ ПОСЛУГИ (залежно від версії IIS).

Можливо, потрібно буде надати ASPNET або СЕТЕВІ ПОСЛУГИ Змінити доступ до папки, де знаходиться web.config.


1
Дякую за відповідь Мітч. Ви відповіли на моє запитання. Що я зробив, це запустив VS 2008 як адміністратор, і все йшло нормально.
jerbersoft

Можливо очевидна для інших (не для мене), ця відповідь, а також відповідь Amin, яка функціонально однакова, фактично перезаписує ваш фізичний файл web.config, а не просто замінює налаштування в пам'яті для конкретного запущеного екземпляра.
k3davis

24

Зміна web.config, як правило, спричиняє перезапуск програми.

Якщо вам дійсно потрібна ваша програма для редагування власних налаштувань, вам слід розглянути інший підхід, наприклад, базу даних налаштувань або створення файлу xml із редагованими налаштуваннями.


1
Привіт, дякую за відповідь. Але є цей клас "Конфігурація", який має функцію "Зберегти". Ви дійсно повинні перезапустити програму, щоб нові налаштування були активними?
jerbersoft

4
Зміна web.config автоматично запускає перезапуск програми.
Mike Cole

1
Не рекомендується динамічно змінювати web.config. Я вважаю за краще зберігати значення у (xml) файлі.
Діпак Мішра

хтось може пояснити, чому перезапуск програми поганий, і багато хто рекомендує перенести атрибут в інший файл?
Бен,

1
@Ben - Я знаю, що минуло кілька місяців, але про всяк випадок - перезапуск програми означатиме, що кожен, хто увійшов у вашу програму в момент перезапуску, автоматично вийде з системи і, швидше за все, зіткнеться з помилкою. (незважаючи на різні сценарії, такі як веб-ферми ...). розлючені користувачі звертаються в
службу

24

І якщо ви хочете уникнути перезапуску програми, ви можете перемістити appSettingsрозділ:

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

в окремий файл. І в поєднанні зConfigurationSaveMode.Minimal

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

Ви можете продовжувати використовувати цей appSettingsрозділ як сховище для різних налаштувань, не викликаючи перезапусків програми та не потребуючи використання файлу з іншим форматом, ніж звичайний розділ AppSettings.


21

2012 Це найкраще рішення для цього сценарію (перевірено на Visual Studio 2008 ):

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

Оновлення 2018 =>
Перевірено проти 2015 року - Asp.net MVC5

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

якщо вам потрібно перевірити наявність елемента, використовуйте цей код:

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

Не могли б ви трохи детальніше пояснити, чому це краще? Я знаю, що речі configSection іноді бувають трохи складними.
julealgon

1
Цей код менший і зрозуміліший! Принаймні для мене.
Амін Гадері

3
О, це через особистий смак тоді, я насправді думав, що це логічно якось інше. Я дуже не згоден з вами в цьому випадку, хоча насправді з багатьох причин: по-перше, тому що вам потрібно вказати один і той же ключ двічі, по-друге, тому, що ви робите, семантично відрізняється від того, що насправді потрібно ('update' vs 'remove-> add ') і третє, оскільки код насправді довший (не впевнений, чому ви тут інакше) і відкритий для помилок. Крім того, що робити, якщо з якихось причин ваш код не справляється між дзвінками? Ваша заявка відтепер зламана, я думаю.
julealgon

2
Цей код видаляє будь-який брат чи коментар до MyVariable.
благус

Так, саме так! Цей код коду повинен бути переписаний на всі змінні, але він працює. але я не рекомендую використовувати його, коли ви використовували код коментаря. Дякую.
Амін Гадері

14

Я знаю, що це питання давнє, але я хотів опублікувати відповідь на основі поточного стану справ у світі ASP.NET \ IIS у поєднанні з моїм реальним світовим досвідом.

Нещодавно я очолив проект у своїй компанії, де я хотів консолідувати та керувати всіма параметрами appSettings & connectionStrings у наших файлах web.config в одному центральному місці. Я хотів застосувати такий підхід, коли наші налаштування конфігурації зберігались у ZooKeeper завдяки зрілості та стабільності проектів. Не кажучи вже про той факт, що ZooKeeper розробляє програму для управління конфігурацією та кластером.

Цілі проекту були дуже простими;

  1. отримати ASP.NET для спілкування з ZooKeeper
  2. у Global.asax, Application_Start - витягніть налаштування web.config із ZooKeeper.

Отримавши технічну частину отримання ASP.NET для розмови із ZooKeeper, я швидко знайшов і вдарився об стіну з таким кодом;

ConfigurationManager.AppSettings.Add(key_name, data_value)

Це твердження мало найбільш логічний сенс, оскільки я хотів додати нові налаштування до колекції appSettings. Однак, як згадував оригінальний плакат (та багато інших), цей виклик коду повертає помилку, в якій зазначається, що колекція призначена лише для читання.

Провівши трохи досліджень і побачивши всі різні божевільні способи роботи людей із цією проблемою, я був дуже знеохочений. Замість того, щоб відмовлятись чи погоджуватися на те, що здавалося менш ідеальним сценарієм, я вирішив копатись і подивитися, чи не пропускаю чогось.

Трохи спроб і помилок, я виявив, що наступний код буде робити саме те, що я хотів;

ConfigurationManager.AppSettings.Set(key_name, data_value)

Використовуючи цей рядок коду, я тепер можу завантажити всі 85 клавіш налаштувань додатків із ZooKeeper у своєму Application_Start.

Що стосується загальних тверджень про зміни в web.config, що викликають переробку IIS, я відредагував наступні налаштування appPool, щоб відстежувати кулуарну ситуацію;

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

За такої комбінації налаштувань, якщо цей процес повинен спричинити переробку appPool, слід записати запис Журналу подій, чого не було.

Це підводить мене до висновку, що можна і справді безпечно завантажувати параметри програм із централізованого носія інформації.

Слід зазначити, що я використовую IIS7.5 у Windows 7. Код буде розгорнуто до IIS8 на Win2012. Якщо щось щодо цієї відповіді зміниться, я відповідно оновлю цю відповідь.


Це, мабуть, просто заощадило мені кілька годин. Дуже дякую!
Drew Delano

4

Хто любить прямо до справи,

У вашому Config

    <appSettings>

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

  </appSettings>

у вашому коді (c #)

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

0

Спробуйте це:

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();
        }
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.