คุณจะแก้ไข 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 หรือ NETWORK SERVICES (ขึ้นอยู่กับเวอร์ชัน IIS)

อาจต้องให้สิทธิ์ ASPNET หรือ NETWORK SERVICES แก้ไขการเข้าถึงในโฟลเดอร์ที่ web.config อยู่


1
ขอบคุณสำหรับการตอบกลับ Mitch คุณตอบคำถามของฉัน สิ่งที่ฉันทำคือเรียกใช้ VS 2008 ในฐานะผู้ดูแลระบบและทุกอย่างก็เรียบร้อยดี
jerbersoft

บางทีอาจจะชัดเจนสำหรับคนอื่น (ไม่ใช่สำหรับฉัน) คำตอบนี้เช่นเดียวกับ Amin ซึ่งมีหน้าที่เหมือนกันเขียนทับไฟล์ web.config ทางกายภาพของคุณไม่เพียงแค่แทนที่การตั้งค่าในหน่วยความจำสำหรับอินสแตนซ์ที่กำลังทำงานอยู่เท่านั้น
k3davis

24

การเปลี่ยน web.config โดยทั่วไปจะทำให้แอปพลิเคชันรีสตาร์ท

หากคุณต้องการให้แอปพลิเคชันของคุณแก้ไขการตั้งค่าของตัวเองจริงๆคุณควรพิจารณาแนวทางอื่นเช่นการตั้งค่าฐานข้อมูลหรือสร้างไฟล์ xml ด้วยการตั้งค่าที่แก้ไขได้


1
สวัสดีขอบคุณสำหรับการตอบกลับ แต่มีคลาส "Configuration" นี้ที่มีฟังก์ชัน "Save" คุณต้องรีสตาร์ทแอปจริงๆเพื่อให้การตั้งค่าใหม่ทำงานได้หรือไม่?
jerbersoft

4
การเปลี่ยน web.config จะทริกเกอร์การรีสตาร์ทแอปพลิเคชันโดยอัตโนมัติ
Mike Cole

1
ไม่ควรแนะนำให้เปลี่ยน web.config แบบไดนามิก ฉันต้องการเก็บค่าไว้ในไฟล์ (xml)
Deepak Mishra

ใครสามารถอธิบายได้ว่าทำไมการรีสตาร์ทแอปพลิเคชันจึงไม่ดีและหลายคนแนะนำให้ย้ายแอตทริบิวต์ไปยังไฟล์อื่น
เบ็น

1
@ เบ็น - ฉันรู้ว่ามันไม่กี่เดือนแล้ว แต่ในกรณี - การรีสตาร์ทแอพจะหมายถึงใครก็ตามที่ลงชื่อเข้าใช้แอพของคุณเมื่อรีสตาร์ทจะถูกออกจากระบบโดยอัตโนมัติและส่วนใหญ่จะพบข้อผิดพลาด (สถานการณ์ต่างๆเช่นเว็บฟาร์มแม้ว่า ... ) ผู้ใช้ที่โกรธติดต่อฝ่ายสนับสนุนติดต่อฝ่ายสนับสนุนคุณ ฯลฯ ฯลฯ ฯลฯ ...
Fetchez la vache

24

และหากคุณต้องการหลีกเลี่ยงการรีสตาร์ทแอปพลิเคชันคุณสามารถย้ายappSettingsส่วน:

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

ไปยังไฟล์แยกต่างหาก และใช้ร่วมกับConfigurationSaveMode.Minimal

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

คุณสามารถใช้appSettingsส่วนนี้เป็นที่เก็บสำหรับการตั้งค่าต่างๆได้โดยไม่ต้องรีสตาร์ทแอปพลิเคชันและไม่จำเป็นต้องใช้ไฟล์ที่มีรูปแบบแตกต่างจากส่วน appSettings ปกติ


22

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
โค้ดนี้มีขนาดเล็กและเข้าใจง่ายขึ้น! อย่างน้อยสำหรับฉัน
Amin Ghaderi

3
โอ้เป็นเพราะรสนิยมส่วนตัวจริงๆแล้วฉันคิดว่ามันแตกต่างกันอย่างมีเหตุผล ฉันไม่เห็นด้วยอย่างยิ่งกับคุณในกรณีนี้ด้วยเหตุผลหลายประการประการแรกเพราะคุณต้องระบุคีย์เดียวกันสองครั้งอันดับที่สองเนื่องจากสิ่งที่คุณกำลังทำนั้นแตกต่างจากความหมายที่แท้จริง ('update' vs 'remove-> add ') และอันดับสามเนื่องจากโค้ดยาวกว่าจริง ๆ (ไม่แน่ใจว่าทำไมคุณถึงเป็นอย่างอื่นที่นี่) และเปิดรับข้อผิดพลาด นอกจากนี้จะเกิดอะไรขึ้นหากรหัสของคุณล้มเหลวระหว่างการโทรด้วยเหตุผลบางประการ ฉันคิดว่าใบสมัครของคุณเสียจากที่นั่น
julealgon

2
รหัสนี้จะลบความคิดเห็นที่เกี่ยวข้องกับ MyVariable
blagus

ใช่แน่นอน! โค้ดโค้ดนี้เขียนใหม่ทุกตัวแปร แต่ใช้งานได้ แต่ฉันไม่แนะนำให้ใช้เมื่อคุณใช้รหัสความคิดเห็น ขอขอบคุณ.
Amin Ghaderi

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)

ด้วยการใช้โค้ดบรรทัดนี้ตอนนี้ฉันสามารถโหลดคีย์ appSettings ทั้งหมด 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();
        }
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.