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

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

问题描述

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

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();

我想将构建我的配置的结果转换为 JObjectJson 以发送到客户端.我该怎么做?我不想为我的设置创建自定义类.

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

我的回答: 合并

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;
    }

推荐答案

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

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.

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

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;
}

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

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.

让我们以下面的 JSON 为例:

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"

因此,上述 Serialize 方法的结果 JSON 将如下所示:

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" }
  }
}

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

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.

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

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天全站免登陆