c#-ASP.NET Core中AppSettings.json内的POCO对象数组

看来这应该真的很简单,我一直在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"
  }
]

}

我尝试绑定到多个模型(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; }
}

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

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

        services.AddOptions();
        services.Configure<EmailOptions>( _configuration.GetSection("Email" ));
        ...

由于某些原因,我的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>>();

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

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

解决方法:

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

我做出了一个错误的假设,即序列化程序会从json中愉快地创建它的列表,并将该列表分配给我的IEnumerable-相反,如果您打算将json对象的列表反序列化到您的Options(和其他)中,则需要确保使用List具体的dotnet类型).

所以代替这个

IEnumerable<EmailTemplate> EmailTemplates { get; set; }    

我应该有这个…

List<EmailTemplate> EmailTemplates { get; set; }
上一篇:c#-为什么.NET Core选项的配置不能与通用类型参数一起使用?


下一篇:ASP.NET Core appsettings.json 文件