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

时间:2018-01-03 18:17:23

标签: c# asp.net-core appsettings

这看起来应该非常简单,我一直在搜索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()”方法使其工作?有更好的方法吗?

1 个答案:

答案 0 :(得分:3)

感谢Joe指出需要发生的事情!

我假设序列化程序很乐意从json创建它的列表并将该列表分配给我的IEnumerable - 而是 - 如果你打算将json对象列表反序列化到你的选项中,你需要确保使用List (以及适用的其他具体dotnet类型)。

所以代替这个

IEnumerable<EmailTemplate> EmailTemplates { get; set; }    

我应该有这个......

List<EmailTemplate> EmailTemplates { get; set; }