ASP.NET Core 6.0 - 从 appsettings.json 获取动态 Json 对象

问题描述 投票:0回答:2

我的 appsettings.json 文件如下所示。在我的program.cs中,我想将请求配置部分提取为Json对象(使用newtonsoft.json)。我无法将其映射到自定义 .NET 对象,因为请求部分的结构和内容在运行 asp.net Web API 的不同环境中会有所不同 - 因此我需要将其提取为 JObject。我该怎么做?我找不到任何将 ConfigSection 转换为 Json 对象的方法

appsettings.json

{
    "ProductConfiguration":
    {
      "CapabilityName": "Tester",
      "Request":
      {
        "Id": 1,
        "Content":
        {
          "User": "TestUser"
        }
      }
    }
}

我尝试了 JObject.Parse(JsonConvert.SerializeObject(service.GetSection("RequestJson")))
但结果为空/不正确

c# asp.net-core json.net appsettings
2个回答
3
投票

来自 .NET 配置文档

配置提供程序使用各种配置源从键值对读取配置数据

因此,您应该将配置视为键值对集,而不是 JSON(并非所有提供程序都是 JSON)。如果您的配置中没有数组,您可以尝试执行以下操作(我正在使用

System.Text.Json
,但如果需要,可以将其迁移到 Newtonsoft):

var configurationSection = builder.Configuration.GetSection("ProductConfiguration");

var root = new JsonObject();
foreach (var (key, s) in configurationSection.AsEnumerable())
{
    JsonNode r = root;
    var keys = key.Split(":");
    foreach (var el in keys[..^1])
    {
        if (r[el] == null)
        {
            r[el] = new JsonObject();
        }

        r = r[el];
    }

    var last = keys[^1];
    if (r[last] == null)
    {
        r[last] = s;
    }
}

Console.WriteLine(root.ToJsonString()); // {"ProductConfiguration":{"Request":{"Id":"1","Content":{"User":"TestUser"}},"CapabilityName":"Tester"}}

但总的来说,我建议使用提供的配置 API(如

AsEnumerable
GetChildren
等)来动态读取值和/或确定对象类型来绑定它。在某些情况下也可以使用
Dictionary<string, string>

此外,您始终可以读取文件并将其解析为 JSON,而不使用配置 API(但在这种情况下,您将失去一些好处,例如环境配置和使用其他配置源)。


0
投票

您可以使用以下代码遍历配置节以获取其所有键值作为对象

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System.Text.Json.Nodes;

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly IConfiguration configuration;
    private readonly ILogger<ValuesController> logger;

    public ValuesController(IConfiguration configuration,ILogger<ValuesController> logger)
    {
        this.configuration = configuration;
        this.logger = logger;
    }
    // GET: api/<ValuesController>
    [HttpGet]
    public IActionResult Get()
    {
        try
        {
            string ParentKey = "ElsticConfig";
            var json = GetConfigSectionAsJson(ParentKey);

            // access JsonObject
            //string? value = json["DataViewsDictionary"]?["General Logs"]?.ToString();

            return Ok(json.ToString());

        }
        catch (Exception ex)
        {
            logger.LogCritical(ex, ex.ToString());
            return StatusCode(StatusCodes.Status500InternalServerError, new { message = ex.ToString() });
        }

    }


    private JsonObject GetConfigSectionAsJson(string ParentKey)
    {
        JsonObject obj = new JsonObject();
        var configurationSection = configuration.GetSection(ParentKey);
        GetConfigInernal(ParentKey, configurationSection, obj);
        return obj;
    }

    private void GetConfigInernal(string parentKey, IConfigurationSection section , JsonObject obj)
    {
        object value = section.Value;
        string key = section.Key.Replace($"{parentKey}:", "");
        if (value is string)
        {
            // The value is a string
            obj.Add(key, value.ToString());
        }
        else
        {
            // The value is an object
            foreach (var newSec in section.GetChildren())
            {
                if (newSec.Value is string)
                {
                    GetConfigInernal(newSec.Path, newSec, obj);
                }
                else
                {
                    var newObj = new JsonObject();
                    GetConfigInernal(newSec.Path, newSec, newObj);
                    obj.Add(newSec.Key, newObj);
                }
            }
        }

        //logger.LogInformation(obj.ToString());
        

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.