C# ASP.NET核心中AppSettings.json内的POCO对象数组

C# ASP.NET核心中AppSettings.json内的POCO对象数组,c#,asp.net-core,appsettings,C#,Asp.net Core,Appsettings,这似乎真的应该很简单,我一直在寻找答案,所以很多其他地方,我已经发现和尝试的一切都不起作用 我有一个appsettings.json文件,如下所示 "Email": { "Port": "25", "Host": "localhost", "EnableSSL": "false", "Credentials": { "Username": "fakeuser", "Password": "fakepassword" }, "SystemFromAddress": "testsender@

这似乎真的应该很简单,我一直在寻找答案,所以很多其他地方,我已经发现和尝试的一切都不起作用

我有一个appsettings.json文件,如下所示

"Email": {
"Port": "25",
"Host": "localhost",
"EnableSSL": "false",
"Credentials": {
  "Username": "fakeuser",
  "Password": "fakepassword"
},
"SystemFromAddress": "testsender@localhost.com",
"SystemFromDisplayName": "Test Sender",
"EmailTemplateRootDirectory": "Email\\EmailTemplates",
"EmailTemplates": [
  {
    "TemplateKey": "ResetPassword",
    "TemplatePath": "ResetPassword.cshtml"
  },
  {
    "TemplateKey": "NewAccount",
    "TemplatePath": "NewAccount.cshtml"
  },
  {
    "TemplateKey": "VerifyEmail",
    "TemplatePath": "VerifyEmail.cshtml"
  }
]
}

我正在尝试绑定多个模型(EmailOptions是父模型),EmailOptions类希望从appsettings.json中的EmailTemplates列表填充其EmailTemplates列表,如上所示

父类按预期由appsettings.json文件填充,该类中电子邮件模板的子列表始终为空

以下是我绑定到的类

public class EmailOptions
{
    public int Port { get; set; }
    public string Host { get; set; }
    public bool EnableSSL { get; set; }
    public EmailCredentials Credentials { get; set; }
    public string SystemFromAddress { get; set; }
    public string SystemFromDisplayName { get; set; }
    public string EmailTemplateRootDirectory { get; set; }

    public IEnumerable<EmailTemplate> EmailTemplates { get; set; } = new List<EmailTemplate>();

}

public class EmailTemplate
{
    public string TemplateKey { get; set; }
    public string TemplatePath { get; set; }
}

public class EmailCredentials
{
    public string Username { get; set; }
    public string Password { get; set; }
}
公共类电子邮件选项
{
公共int端口{get;set;}
公共字符串主机{get;set;}
公共布尔启用SSL{get;set;}
公共电子邮件凭据凭据{get;set;}
公共字符串SystemFromAddress{get;set;}
公共字符串SystemFromDisplayName{get;set;}
公共字符串EmailTemplateRootDirectory{get;set;}
public IEnumerable EmailTemplates{get;set;}=new List();
}
公共类电子邮件模板
{
公共字符串TemplateKey{get;set;}
公共字符串模板路径{get;set;}
}
公共类电子邮件凭据
{
公共字符串用户名{get;set;}
公共字符串密码{get;set;}
}
我在ASP.NET Core的startup类中使用以下调用

public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        services.AddOptions();
        services.Configure<EmailOptions>( _configuration.GetSection("Email" ));
        ...
public void配置服务(IServiceCollection服务)
{
services.AddMvc();
services.AddOptions();
services.Configure(_configuration.GetSection(“电子邮件”));
...
出于某种原因,我的EmailOptions中的IEnumerable属性没有从appsettings.json反序列化到我的选项中—当我尝试在控制器中的任何位置使用它时—列表始终设置为空数组

FWIW:在控制台应用程序中,我可以通过appsettings.json更多地控制设置选项。以下是我在控制台应用程序中所做的操作(为了简洁起见,我省略了使用DI容器设置选项的代码)

var-emailSection=configuration.GetSection(“电子邮件”);
var emailOptions=emailSection.Get();
emailOptions.EmailTemplates=configuration.GetSection(“电子邮件:EmailTemplates”).Get();
正如预期的那样-在控制台应用程序中,我获取电子邮件模板是因为我能够单独获取子列表,并在将其移交给DI容器之前将其添加到选项中。在ASP.NET Core IServicCollection.Configure()扩展方法中,我似乎没有这种灵活性(因此,也许可以用另一种方法来做这件事?哪一种?经过几个小时的搜索,我哭了叔叔并请求帮助)


那么,如何使用ASP.NET核心的“IServiceCollection.Configure()”方法来实现这一点呢?有没有更好的方法来实现这一点?

感谢Joe指出需要做什么

我错误地假设序列化程序会很高兴地从json创建它的列表,并将该列表分配给我的IEnumerable——相反,如果您打算将json对象列表反序列化到您的选项(以及其他具体的dotnet类型,如果适用的话),则需要确保使用list

所以不是这个

IEnumerable<EmailTemplate> EmailTemplates { get; set; }    
IEnumerable EmailTemplates{get;set;}
我应该有这个

List<EmailTemplate> EmailTemplates { get; set; }
列出电子邮件模板{get;set;}

IEnumerable是一个可以由多种类型实现的接口,反序列化程序无法猜测。您应该将其更改为列表,然后反序列化程序将知道如何反序列化。就是这样。太简单了,我错过了。非常感谢您的帮助!
List<EmailTemplate> EmailTemplates { get; set; }