如何正确读取ASP.NET5中config.json中的嵌套配置值

本文关键字:嵌套 配置 json config 读取 ASP NET5 何正确 | 更新日期: 2023-09-27 17:49:45

我在学习ASP.NET 5的一些示例时,遇到了如何正确读取"嵌套"配置值的问题(如果这是正确的术语的话(。

以下是config.json:的相关部分

{
    "ApplicationName" : "OwNextApp",
    "AppSettings": {
        "SiteTitle": "OwNext"
    },
}

以及HomeController.cs:的相关部分

public IActionResult About()
{
    var appNestedNameFailed = _config.Get("AppSettings.SiteTitle");
    var appNestedNameSuccess = _config.Get("AppSettings:SiteTitle");
    var appName = _config.Get("ApplicationName");
    ViewBag.Message = string.Format(@"Your 
        APP NAME: {0};
        APP NESTED NAME FAILED: {1}; 
        APP NESTED NAME SUCCESS: {2}", 
            appName, appNestedNameFailed, appNestedNameSuccess);
    return View();
}

appNestedNameFailed的值为空(我在研究前的首次尝试(。并且CCD_ 4具有值;在我做了研究并在配置测试中发现(显示了相关代码(:

// Assert
Assert.Equal("IniValue1", config.Get("IniKey1"));
Assert.Equal("IniValue2", config.Get("IniKey2:IniKey3"));

有人能解释为什么会这样吗?为什么使用:而不是.是有意义的?从我与JSON数据的交互来看,.表示法通常很好,例如如何访问嵌套的JSON数据。

此外,我发现了类似的SO问题,但这并不能解释为什么选择:

如何正确读取ASP.NET5中config.json中的嵌套配置值

这是我们第一次创建配置模型时决定的约定。我们从json开始,:是其中的分隔符。

无论如何,如果您不想担心这些约定,我建议使用ConfigurationBinder,它将配置绑定到模型(强类型对象(。以下是GitHub上的测试,可以作为示例。

using Microsoft.Extensions.Configuration;
using System.IO;
IConfigurationRoot configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
var connectionString = configuration.GetValue<string>("ConnectionStrings:DefaultConnection");
// or
var connectionString2= configuration.GetSection("ConnectionStrings").GetSection("DefaultConnection").Value;  

appsettings.json:

{
  "ConnectionStrings": {
    "DefaultConnection": "myconnection"
  },
}

深入JsonConfigurationFileParser源代码的内部,指责进入/退出方法:

private void VisitJObject(JObject jObject)
{
    foreach (var property in jObject.Properties())
    {
        EnterContext(property.Name);
        VisitProperty(property);
        ExitContext();
    }
}
private void EnterContext(string context)
{
    _context.Push(context);
    _currentPath = string.Join(":", _context.Reverse());
}
private void ExitContext()
{
    _context.Pop();
    _currentPath = string.Join(":", _context.Reverse());
}

ASP.NET团队似乎应该留下更具启发性的签入注释:(。

我的最佳猜测是,config.json文件中可能存储了需要包含.的数据,而:则不太常见。例如:

"AppSettings": {
    "Site.Title": "Is .NET getting faster?"
},

这是一个糟糕的例子,但他们希望尽可能"安全",并使用超出规范的东西,这似乎是合理的。如果你想存储一个类型的全名,这也会稍微容易一些,而不需要担心有一个游离的句点。

"AppSettings": {
    "ImportantTypeName": "WebApp.CoolStuff.Helpers.AwesomeClass"
},