在 dotnet 核心中,对 config.GetSection().Get <List<object>> 的调用不会将值加载到对象中

Posted

技术标签:

【中文标题】在 dotnet 核心中,对 config.GetSection().Get <List<object>> 的调用不会将值加载到对象中【英文标题】:In dotnet core the call to config.GetSection().Get <List<object>> will not load values into the object 【发布时间】:2020-04-09 05:19:16 【问题描述】:

在我的 appsetting.json 中,我定义了以下值数组。

"DirectoriesToMonitor": [
  
    "DirectoryToMonitor": 
      "Directory": "c:\\temp1",
      "IncludeSubDirectories": true,
      "FileTypes": "txt",
      "ZipFiles": false,
      "NotifyOnly": true
    
  ,
  
    "DirectoryToMonitor": 
      "Directory": "c:\\temp2",
      "FileTypes": "txt",
      "ZipFiles": false,
      "NotifyOnly": true
    
  
]

我正在尝试使用此语句将它们加载到对象列表中。

List<DirectoryToMonitor> dirs = config.GetSection("DirectoriesToMonitor").Get<List<DirectoryToMonitor>>();

“目录”列表中填充了 2 个对象,但每个对象的属性都不是从 appsettings 加载的。

我也试过这个:

List<DirectoryToMonitor> directories = new List<DirectoryToMonitor>();
config.Bind("DirectoriesToMonitor", directories);

我得到了同样的结果。

namespace FileWatcherEmailer

    public class DirectoryToMonitor
    
        public string Directory  get; set; 
        public bool IncludeSubDirectories  get; set; 
        public string FileTypes  get; set; 
        public bool ZipFiles  get; set; 
        public bool NotifyOnly  get; set; 
    

【问题讨论】:

这能回答你的问题吗? ASP.NET Core Get Json Array using IConfiguration 它确实有一些关于我可以解决这个问题的其他方法的建议,但我很想知道为什么 config.Bind 语句不起作用。我认为这是我做过或没做过的事情。处理 POCO 比解析返回值并从中填充对象要优雅得多。 这个答案可以帮助你***.com/a/41331380/418175 对象与 JSON 数据不匹配。 JSON 文件包含一个对象数组,该数组具有一个名为 DirectoryToMonitor 的属性,而不是具有 DirectoryFileTypes 等的对象。DirectoryToMonitor 字符串是字段名称,而不是类型名称。您需要修改 JSON 文件以包含内部属性,或者创建一个具有单个 DirectoryToMonitor 属性的新类,该属性包含一个 DirectoryToMonitor 对象 【参考方案1】:

您必须将 Base 类更改为此

public class DirectoryToMonitor

    public string Directory  get; set; 
    public bool IncludeSubDirectories  get; set; 
    public string FileTypes  get; set; 
    public bool ZipFiles  get; set; 
    public bool NotifyOnly  get; set; 


public class DirectoriesToMonitor

    public DirectoryToMonitor DirectoryToMonitor  get; set; 


public class RootObject

    public List<DirectoriesToMonitor> DirectoriesToMonitor  get; set; 

最后将json绑定到List&lt;DirectoriesToMonitor&gt;

List<DirectoriesToMonitor> directories = new List<DirectoriesToMonitor>();
config.GetSection("DirectoriesToMonitor").Bind(directories);

或者

List<DirectoriesToMonitor> directories = new List<DirectoriesToMonitor>();
config.Bind("DirectoriesToMonitor", directories);

【讨论】:

【参考方案2】:

DirectoryToMonitor 对象与 JSON 文件匹配。该文件包含具有单个属性的对象数组,而这些对象又包含与DirectoryToMonitor 类匹配的属性。

JSON 文件中的"DirectoryToMonitor" 字符串指定一个字段,而不是对象类型。 JSON 没有类型,任何 JSON 反序列化器都会将 JSON 片段反序列化为与其内容匹配的任何类型。

为了让您的代码正常工作,JSON 文件应如下所示:

"DirectoriesToMonitor": [
  
    "Directory": "c:\\temp1",
    "IncludeSubDirectories": true,
    "FileTypes": "txt",
    "ZipFiles": false,
    "NotifyOnly": true
  ,
    "Directory": "c:\\temp2",
    "FileTypes": "txt",
    "ZipFiles": false,
    "NotifyOnly": true
  
]

如果要保持文件不变,则需要使用具有单个DirectoryToMonitor 属性的新类,其中包含DirectoryToMonitor 对象:

class DirectoryToMonitorDTO 

    public DirectoryToMonitor DirectoryToMonitor get; set;

代码必须改为:

List<DirectoryToMonitor> directories =
    config.GetSection("DirectoriesToMonitor")
          .Get<List<DirectoryToMonitorDTO>>()
          .Select(dto=>dto.DirectoryToMonitor)
          .ToList();

【讨论】:

以上是关于在 dotnet 核心中,对 config.GetSection().Get <List<object>> 的调用不会将值加载到对象中的主要内容,如果未能解决你的问题,请参考以下文章

dotnet 核心的 String.Copy 替代方案

dotnet 核心中的 Dbcontext 对象瞬态

Rider 说无法更新路径“/usr/share/dotnet/dotnet”中的 dotnet 核心

无法启动 dotnet 核心进程。添加工具失败

Dotnet 核心中的 LoggerFactory 如何被调用

分析在 Kubernetes Linux 中运行的 dotnet 核心进程的内存转储