如何通过 c# Windows 表单应用程序读取和更新外部 web.config

How to read and update external web.config by a c# Windows forms application

我正在构建一个 c# Windows 应用程序来维护一个 WEB 应用程序——专门用于在 web.config 文件中创建和更新值。我在这里尝试了很多建议,但所有建议都只是描述从应用程序内部读取和写入配置文件。 web.config的一部分:

- 
 <configuration>
    <system.web>
        <customErrors mode="Off"/>

        <compilation debug="true" targetFramework="4.0" />
        <globalization culture="" enableClientBasedCulture="true" uiCulture="" />

        <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID" />
    </system.web>
    <appSettings>
        <add key="DocPath" value="~/serverdocs/docs" />

        <add key="TextForLabel1" value="This is some text"/>
..

我尝试读取文件 - 特殊来自 appSettings 的所有键 - 如

    var xmlDoc = new XmlDocument();
        xmlDoc.Load(FName); // name and path from web.config file

然后读取所有节点,如:

            foreach (XmlNodeList xmlnodes in xmlDoc.SelectNodes("configuration/appSettings"))
            {
                foreach ( XmlNode node in xmlnodes)
                {
                string MyKey = node.Name;
                string MyVal = node.Value;
                }

            }  

但是总是会出现这样的错误 类型 "System.Xml.XmlDeclaration" 的对象无法转换为类型 "System.Xml.XmlNodeList"。或者根本找不到这些项目,具体取决于我如何编写 select 值。 我已经尝试过 '//configuration' 和 'configuration/appSettings' 等。

有时我可能会盲目阅读自己的代码并检测到错误 - 抱歉 - 欢迎任何建议。

尽管配置文件是 XML,但在 XmlDocument.

中可能难以枚举和定位它们

相反,您实际上可以使用专门设计用于读取和写入 web.config 文件的 WebConfigurationManager

Configuration cfg = WebConfigurationManager.OpenWebConfiguration("YOUR_WEB_CONFIG");

Configuration 对象中获得数据后,您可以枚举配置文件的部分和值​​。

您需要添加对 System.ConfigurationSystem.Web 的引用才能使用上述内容。

编辑

根据 Willhelm 的评论,他无法从文件的物理路径打开 web.config,以下代码片段(直接从 this answer 窃取)可用于加载文件:

public static Configuration OpenConfigFile(string configPath)
{
    var configFile = new FileInfo(configPath);
    var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
    var wcfm = new WebConfigurationFileMap();
    wcfm.VirtualDirectories.Add("/", vdm);
    return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
}

使用:

Configuration cfg = OpenConfigFile(@"YOUR_WEB_CONFIG");

我遇到了类似的问题,并沿着与您相同的道路前进,试图遍历 XML 树以找到我需要更改的节点。它是一个 key/value 对,定义了 Web 服务连接的 URI。默认 URI 指向本地主机,例如:

    <add key="ProcessorService" value="https://localhost/Processor/ProcessorService.asmx" />

...我需要将它指向服务实际 运行 所在的服务器,这取决于它在哪个机器上运行(Dev、QA、UAT、Prod 等)

我竭尽全力试图走过那棵愚蠢的树,并且有八个不同的 Web 配置需要对安装站点的每个服务器进行类似的修改。当然,每个 web.config 的结构都不同。

我在站点的 PowerShell 安装脚本中使用正则表达式解决了这个问题,这里是一个片段:

(Get-Content $webConfig -Encoding UTF8) | `
    ForEach-Object {$_ -replace 'localhost', "$dnsName" } | `
    Set-Content $webConfig

我 运行 上面的循环内部遍历每个目录中的每个 web.config 文件,进行修改,然后使用 Set-Content cmdlet 保存文件。

我能理解,如果您要在 C# 中执行此操作,您总是可以将文件作为流打开,设置一些 Regex 对象,然后基本上执行同样的操作。

我?就个人而言,除非迫不得已,否则我讨厌走路 XML。你当然可以那样做,但如果有人出现并后方运行ges你的web.config文件,他们会破坏你精心制作的XML助行器,你将开始所有超过。这样,只要您要更改的内容没有(太多)更改,它就可以正常工作。

阅读:

   var xmlDoc = new XmlDocument();
    xmlDoc.Load(FName);
    DataTable DTConfig = new DataTable();
    DTConfig.Columns.Add("Key", typeof(string));
    DTConfig.Columns.Add("Value", typeof(string));
    DTConfig.Columns.Add("OldValue", typeof(string));
    try
    {
        foreach (XmlElement xmlElement in xmlDoc.SelectNodes("configuration/appSettings"))
        {
            foreach (XmlNode node in xmlElement)
            {
                if (node.Attributes != null && node.Attributes.Count > 1)
                {
                    string MyKey = "";
                    string MyVal = "";
                    if (node.Attributes[0].Value != null)
                    {
                        MyKey = node.Attributes[0].Value;
                    }
                    if (node.Attributes[1].Value != null)
                    {
                        MyVal = node.Attributes[1].Value;
                    }
                    DataRow DR = DTConfig.NewRow();
                    DR["Key"] = MyKey;
                    DR["Value"] = MyVal;
                    DR["OldValue"] = MyVal;
                    if (MyKey != "")
                    {
                        DTConfig.Rows.Add(DR);
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        Debug.Print(ex.Message);
    }
    TxtFname.Text = FName;
    DGConfig.DataSource = DTConfig;
    return true;

数据表绑定到数据网格视图 - 仅此而已