首页 > 解决方案 > 使用 'node:child' 表示法搜索 json 属性的最佳方法

问题描述

在基于 MSI 的安装过程中,我们有一个过程,即我们通过参数和/或安装程序表单获取 appsetting 值。

我正在尝试动态更新应用程序 appsettings 文件的 json 属性,但不确定如何使用“node:child:child”的密钥格式在任何深度搜索 json。所有选项都在桌面上,我们能够序列化对象并使用反射、linq 解决方案或其他任何东西。这将非常类似于 json 替换在 Azure 构建或发布管道中的工作方式。

目前有这个非常接近,除了我无法从 IConfiguration 中提取 json 字符串以便将其写回文件.....

public static ActionResult ModifySettings(Session session)
        {
            session.Log("Begin ModifySettings");

            try
            {
                string[] customData = session.CustomActionData.Keys.ToArray();
                string[] customValues = session.CustomActionData.Values.ToArray();

                ///Product.wxs -> BinDir=[BinDir]
                var installDirectory = customValues[1];
                string file = Path.Combine(installDirectory, "appsettings.json");

                session.Log(string.Format($"Updating file: {file}.{Environment.NewLine}."));

                if (File.Exists(file))
                {
                    session.Log($"Updating Settings file: {file}.{Environment.NewLine}");

                    var configFile = new ConfigurationBuilder().AddJsonFile(file).Build();                    

                    for (int i = 3; i < customData.Count(); i++)
                    {
                        if (!ReplaceSetting(configFile, customData[i], customValues[i], session))
                            throw new ArgumentException($"Error during settings replacement of {customData[i]} with {customValues[i]}",customData[i]);
                    }

                    var settingsAsString = configFile.ToString();//DOES NOT WORK
                    session.Log($"Updated settings{Environment.NewLine}{settingsAsString}{Environment.NewLine}");
                    File.WriteAllText(file, settingsAsString);
                }
                else
                {
                    session.Log($"Failed to update file {file}.{Environment.NewLine}Exiting.");
                    return ActionResult.Failure;
                }

                return ActionResult.Success;
            }catch(Exception ex)
            {
                session.Log(ex.Message);
                return ActionResult.Failure;
            }
        }
 private static bool ReplaceSetting(IConfigurationRoot settings, string settingName, string settingValue, Session session)
        {
            try
            {
                session.Log(string.Format($"Updating Setting: {settingName}{Environment.NewLine}Value: {settingValue}{Environment.NewLine}"));
                settings[settingName] = settingValue; //<- THIS IS THE PART I NEED TO MIMIC WHEN SETTINGNAME FORMAT IS SOMETHING:SOMETHINGELSE:PROPERTY!!!
            }
            catch(Exception ex)
            {
                session.Log(ex.Message);
                return false;
            }
            return true;
        }

使用 JObject 编辑工作解决方案

 public static ActionResult ModifySettings(Session session)
        {
            session.Log("Begin ModifySettings");

            try
            {
                string[] customData = session.CustomActionData.Keys.ToArray();
                string[] customValues = session.CustomActionData.Values.ToArray();

                ///Product.wxs -> BinDir=[BinDir]
                var installDirectory = customValues[1];
                string file = Path.Combine(installDirectory, "appsettings.json");

                session.Log(string.Format($"Updating file: {file}.{Environment.NewLine}."));

                if (File.Exists(file))
                {
                    session.Log($"Updating Settings file: {file}.{Environment.NewLine}");

                    var configFile = new ConfigurationBuilder().AddJsonFile(file).Build();
                    JObject settings = JObject.Parse(File.ReadAllText(file));

                    for (int i = 3; i < customData.Count(); i++)
                    {
                        if (!ReplaceSetting(ref settings, customData[i], customValues[i], session))
                            throw new ArgumentException($"Error during settings replacement of {customData[i]} with {customValues[i]}",customData[i]);
                    }

                    session.Log($"Updated settings{Environment.NewLine}{settings.ToString()}{Environment.NewLine}");
                    File.WriteAllText(file, settings.ToString());
                }
                else
                {
                    session.Log($"Failed to update file {file}.{Environment.NewLine}Exiting.");
                    return ActionResult.Failure;
                }

                return ActionResult.Success;
            }catch(Exception ex)
            {
                session.Log(ex.Message);
                return ActionResult.Failure;
            }
        }

private static bool ReplaceSetting(ref JObject settingFile, string settingName, string settingValue, Session session)
        {
            try
            {
                session.Log(string.Format($"Updating Setting: {settingName}{Environment.NewLine}Value: {settingValue}{Environment.NewLine}"));
                var token = settingFile.SelectToken(settingName);
                (token.Parent as JProperty).Value = settingValue;
            }
            catch (Exception ex)
            {
                session.Log(ex.Message);
                return false;
            }
            return true;
        }

标签: c#json

解决方案


推荐阅读