ASP.NET Core 中 AppSettings.json 中的 POCO 对象数组

Cha*_*mas 9 c# appsettings asp.net-core

这看起来应该很简单,我一直在搜索 SO 和许多其他地方以寻找答案,我发现并尝试过的一切都不起作用。

我有一个看起来像这样的 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"
  }
]
Run Code Online (Sandbox Code Playgroud)

}

我正在尝试绑定多个模型(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; }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用我在 ASP.NET Core 的启动类中进行的以下调用。

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

        services.AddOptions();
        services.Configure<EmailOptions>( _configuration.GetSection("Email" ));
        ...
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我的 EmailOptions 中的 IEnumerable 属性没有从 appsettings.json 反序列化到我的选项中 - 当我尝试在我的控制器中的任何地方使用它时 - 该列表始终设置为空数组。

FWIW:我在控制台应用程序中进行了这项工作,在那里我可以更好地控制从 appsettings.json 设置我的选项。这是我在控制台应用程序中所做的事情,(为简洁起见,我省略了使用 DI 容器设置选项的代码)

var emailSection = configuration.GetSection( "Email" );
var emailOptions = emailSection.Get<EmailOptions>();

emailOptions.EmailTemplates = configuration.GetSection( "Email:EmailTemplates" ).Get<List<EmailTemplate>>();
Run Code Online (Sandbox Code Playgroud)

正如预期的那样 - 在控制台应用程序中,我得到了我的电子邮件模板,因为我能够单独获取子列表并将其添加到选项中,然后再将其移交给 DI 容器。我似乎在 ASP.NET Core IServiceCollection.Configure() 扩展方法中没有那种灵活性(所以也许使用另一种方法来做到这一点?哪个?经过几个小时的搜索,我哭了叔叔并寻求帮助) .

那么如何使用 ASP.NET Core“IServiceCollection.Configure()”方法让它工作呢?有一个更好的方法吗?

Cha*_*mas 14

谢谢乔指出需要发生的事情!

我做了一个错误的假设,即序列化程序很乐意从 json 创建它的列表并将该列表分配给我的 IEnumerable - 相反 - 如果您打算将 json 对象列表反序列化到您的选项(和其他适用的具体 dotnet 类型)。

所以而不是这个

IEnumerable<EmailTemplate> EmailTemplates { get; set; }    
Run Code Online (Sandbox Code Playgroud)

我应该有这个...

List<EmailTemplate> EmailTemplates { get; set; }
Run Code Online (Sandbox Code Playgroud)