在2个配置文件之间传输值

时间:2016-07-29 17:54:29

标签: c# json dynamic json-deserialization

我有一个问题,我自己无法解决这个问题。 在我的程序中,我有一个自动更新程序,当我的程序更新时,创建了一个新的(更改的,一些新的密钥)配置文件。我希望我的程序要做的是,当它更新以查看配置文件(旧的和新的)并将旧文件中与新文件中的键匹配的旧设置传输到新文件时。

这是旧文件的示例:

scale

这可以是新文件(也可以是不同的):

 {
  "Setting1": false,
  "Setting2": 123,
  "Setting3": "test",
  "LocationList": {
    "Country": "NL",
    "Locations": [
      {
        "Latitude": 38.556807486461118,
        "Longitude": -121.2383794784546
      },
      {
        "Latitude": -33.859019,
        "Longitude": 151.213098
      },
      {
        "Latitude": 47.5014969,
        "Longitude": -122.0959568
      },
      {
        "Latitude": 51.5025343,
        "Longitude": -0.2055027
      }
    ]
  }
}

预期结果:

{
  "Setting1": null,
  "Setting2": null,
  "Setting3": "",
  "Setting4": ""
  "LocationList": {
    "Country": "",
    "Locations": [
      {
        "Latitude": null,
        "Longitude": null
      },
      {
        "Latitude": null,
        "Longitude": null
      }
    ]
  }
}

首先,我看了在c#中创建一个类并且只是反序列化它,然后,我得出结论,这是不可能的,因为我不知道配置会是什么样的。

其次,我认为使用动态可以做到这一点,但事实并非如此,因为我不知道其中的任何键。并且无法弄清楚如何解决这个问题。

最后,我看看是否有可能使用正则表达式,对我来说,这似乎是不可能的..

有人可以给我一些他们会怎么做的想法吗?我不需要代码,只需要朝着正确的方向前进。

P.S。我不想把两者结合起来,当旧文件中有一个键而不是新文件中的一个键时,它不需要传输(只有列表将从旧文件中完全传输,当列表是空的/填写新的)。

3 个答案:

答案 0 :(得分:0)

  

我不需要代码,只需要朝着正确的方向前进。

将您的配置存储在常规App.config文件中并利用System.Configuration。根据配置复杂性,您可以使用ready <appSettings>或构建自己的配置部分和元素。它比自定义配置更容易和错误证明。

这个问题太复杂了,不能开始发明轮子只是为了使用另一种(文本)格式。即使您解决了当前的问题,也会有更多,已经在System.Configration ...

内的某处解决了

您可以开始探索配置选项here;无论如何,在你最喜欢的搜索引擎中定期搜索就可以了!...

答案 1 :(得分:0)

如果您真的想在JSON中尝试一些东西,我只能推荐优秀的JSON.Net库来为您解析json。使用LINQ to JSON,您可以在旧配置文件和较新配置文件之间以递归方式轻松找到匹配的密钥,只需将值从一个复制到另一个

请参阅文档和http://www.newtonsoft.com/json/help/html/LINQtoJSON.htm

的小例子

简单地说,你可以在pseudoCode中这样做。显然这不会超级高效,因为你会递归地多次遍历两个文件并且可以进行优化,但同时除非你的配置文件是怪异的blob,否则这不应该对任何现代硬件造成任何问题

//load both config files

//load the first token in original file and walk recursively

 //for each token try to match in the new file and write data if required using the same recursive technique to walk the other file

答案 2 :(得分:0)

在遇到麻烦之后,我已经设法解决了这个问题(谢谢@Louis)。

我就是这样做的:

        private static bool TransferConfig(string baseDir, ISession session)
        {
            //if (!session.LogicSettings.TransferConfigAndAuthOnUpdate)
            //    return false;

            var configDir = Path.Combine(baseDir, "Config");
            if (!Directory.Exists(configDir))
                return false;

            var oldConf = GetJObject(Path.Combine(configDir, "config.json.old"));
            var oldAuth = GetJObject(Path.Combine(configDir, "auth.json.old"));

            GlobalSettings.Load("");

            var newConf = GetJObject(Path.Combine(configDir, "config.json"));
            var newAuth = GetJObject(Path.Combine(configDir, "auth.json"));

            TransferJSON(oldConf, newConf);
            TransferJSON(oldAuth, newAuth);

            File.WriteAllText(Path.Combine(configDir, "config.json"), newConf.ToString());
            File.WriteAllText(Path.Combine(configDir, "auth.json"), newAuth.ToString());

            return true;
        }

        private static JObject GetJObject(string filePath)
        {
            return JObject.Parse(File.ReadAllText(filePath));
        }

        private static bool TransferJSON(JObject oldFile, JObject newFile)
        {
            try
            {
                foreach (var newProperty in newFile.Properties())
                    foreach (var oldProperty in oldFile.Properties())
                        if (newProperty.Name.Equals(oldProperty.Name))
                        {
                            newFile[newProperty.Name] = oldProperty.Value;
                            break;
                        }

                return true;
            }
            catch
            {
                return false;
            }
        }