如何将IConfigurationRoot或IConfigurationSection转换为JObject/JSON [英] How convert IConfigurationRoot or IConfigurationSection to JObject/JSON

查看:289
本文介绍了如何将IConfigurationRoot或IConfigurationSection转换为JObject/JSON的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Program.cs 中有以下代码:

  var配置=新的ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("clientsettings.json",可选:true,reloadOnChange:true).AddJsonFile($"clientsettings.{host.GetSetting(" environment)}.json",可选:true,reloadOnChange:true).AddEnvironmentVariables().建造(); 

我想将构建配置的结果转换为JObject \ Json以发送给客户端.我该怎么做?而且我不想为自己的设置创建自定义类.

我的答案:合并

 公共静态JObject GetSettingsObject(字符串environmentName){object [] fileNames = {"settings.json",$"settings.{environmentName} .json"};var jObjects = new List< object>();foreach(文件名中的var fileName){var fPath = Directory.GetCurrentDirectory()+ Path.DirectorySeparatorChar + fileName;如果(!File.Exists(fPath))继续;使用(var file = new StreamReader(fPath,Encoding.UTF8))jObjects.Add(JsonConvert.DeserializeObject(file.ReadToEnd()));}如果(jObjects.Count == 0)抛出新的InvalidOperationException();var result =(JObject)jObjects [0];对于(var i = 1; i< jObjects.Count; i ++)result.Merge(jObjects [i],新的JsonMergeSettings{MergeArrayHandling = MergeArrayHandling.Merge});返回结果;} 

解决方案

由于配置实际上只是一个键值存储,其中键具有某种表示路径的格式,因此将其序列化回JSON并不是那么简单./p>

您可以做的是递归地遍历配置子级并将其值写入 JObject .看起来像这样:

  public JToken Serialize(IConfiguration config){JObject obj =新的JObject();foreach(config.GetChildren()中的var child){obj.Add(child.Key,Serialize(child));}如果(!obj.HasValues&&config是IConfigurationSection部分)返回新的JValue(section.Value);返回obj;} 

请注意,这在输出外观上极为有限.例如,数字或布尔值(它们是JSON中的有效类型)将表示为字符串.而且由于数组是通过数字键路径(例如 key:0 key:1 )表示的,因此您将获得作为索引字符串的属性名称.

让我们以以下JSON为例:

  {"foo":"bar",酒吧": {"a":字符串","b":123,"c":是},巴兹":[{"x":1,"y":2},{"x":3,"y":4}]} 

这将通过以下关键路径在配置中表示:

 "foo"->酒吧""bar:a"->细绳""bar:b"->"123""bar:c"->真的""baz:0:x"->"1""baz:0:y"->"2""baz:1:x"->"3""baz:1:y"->"4" 

这样,上述 Serialize 方法的结果JSON看起来像这样:

  {"foo":"bar",酒吧": {"a":字符串","b":"123","c":"true"},"baz":{"0":{"x":"1","y":"2"},"1":{"x":"3","y":"4"}}} 

因此,这将不允许您取回原始表示.就是说,当再次使用 Microsoft.Extensions.Configuration.Json 读取结果JSON时,它生成相同的配置对象.因此,您可以使用它来将配置存储为JSON.

如果您想要更漂亮的东西,则必须添加逻辑来检测数组和非字符串类型,因为这两者都不是配置框架的概念.


我想将 appsettings.json appsettings.{host.GetSetting("environment")}.json 合并到一个对象[并将其发送给客户端]

请记住,特定于环境的配置文件通常包含不应该离开计算机的机密.对于环境变量尤其如此.如果要传输配置值,请确保在构建配置时不要包括环境变量.

I have the following code in my Program.cs:

var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("clientsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"clientsettings.{host.GetSetting("environment")}.json", optional: true, reloadOnChange: true)
                .AddEnvironmentVariables()
                .Build();

I want to convert the result of building my configuration to JObject\Json for sending to the client. How can I do it? and I don't want to create my custom class for my settings.

My answer: merge

public static JObject GetSettingsObject(string environmentName)
    {
        object[] fileNames = { "settings.json", $"settings.{environmentName}.json" };


        var jObjects = new List<object>();

        foreach (var fileName in fileNames)
        {
            var fPath = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + fileName;
            if (!File.Exists(fPath))
                continue;

            using (var file = new StreamReader(fPath, Encoding.UTF8))
                jObjects.Add(JsonConvert.DeserializeObject(file.ReadToEnd()));
        }


        if (jObjects.Count == 0)
            throw new InvalidOperationException();


        var result = (JObject)jObjects[0];
        for (var i = 1; i < jObjects.Count; i++)
            result.Merge(jObjects[i], new JsonMergeSettings
            {
                MergeArrayHandling = MergeArrayHandling.Merge
            });

        return result;
    }

解决方案

Since configuration is actually just a key value store where the keys have a certain format to represent a path, serializing it back into a JSON is not that simple.

What you could do is recursively traverse through the configuration children and write its values to a JObject. This would look like this:

public JToken Serialize(IConfiguration config)
{
    JObject obj = new JObject();
    foreach (var child in config.GetChildren())
    {
        obj.Add(child.Key, Serialize(child));
    }

    if (!obj.HasValues && config is IConfigurationSection section)
        return new JValue(section.Value);

    return obj;
}

Note that this is extremely limited in how the output looks. For example, numbers or booleans, which are valid types in JSON, will be represented as strings. And since arrays are represented through numerical key paths (e.g. key:0 and key:1), you will get property names that are strings of indexes.

Let’s take for example the following JSON:

{
  "foo": "bar",
  "bar": {
    "a": "string",
    "b": 123,
    "c": true
  },
  "baz": [
    { "x": 1, "y": 2 },
    { "x": 3, "y": 4 }
  ]
}

This will be represented in configuration through the following key paths:

"foo"      -> "bar"
"bar:a"    -> "string"
"bar:b"    -> "123"
"bar:c"    -> "true"
"baz:0:x"  -> "1"
"baz:0:y"  -> "2"
"baz:1:x"  -> "3"
"baz:1:y"  -> "4"

As such, the resulting JSON for the above Serialize method would look like this:

{
  "foo": "bar",
  "bar": {
    "a": "string",
    "b": "123",
    "c": "true"
  },
  "baz": {
    "0": { "x": "1", "y": "2" },
    "1": { "x": "3", "y": "4" }
  }
}

So this will not allow you to get back the original representation. That being said, when reading the resulting JSON again with Microsoft.Extensions.Configuration.Json, then it will result in the same configuration object. So you can use this to store the configuration as JSON.

If you want anything prettier than that, you will have to add logic to detect array and non-string types, since both of these are not concepts of the configuration framework.


I want to merge appsettings.json and appsettings.{host.GetSetting("environment")}.json to one object [and send that to the client]

Keep in mind that environment-specific configuration files often contain secrets that shouldn’t leave the machine. This is also especially true for environment variables. If you want to transmit the configuration values, then make sure not to include the environment variables when building the configuration.

这篇关于如何将IConfigurationRoot或IConfigurationSection转换为JObject/JSON的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆