如何使用POCO对象访问appsettings.json文件中的选项数组(ASP.NET 5)

Ape*_*lus 5 json configuration-files appsettings asp.net-core

我正在使用ASP.NET 5,我想使用POCO类来访问我的appsettings.json文件.这个文件看起来像这样:

{
  "Data": {
        "ErpSystemConnection": {
            "ConnectionString": "[myConnectionString]"
        }
  },
    "Logging": {
        "IncludeScopes": false,
        "LogLevel": {
            "Default": "Verbose",
            "System": "Information",
            "Microsoft": "Information"
        }
    },
    "GoogleAnalytics": {
        "Account": [
            {
                "Name": "AccountName",
                "ServiceAccountEmailAddress": "someEmail@someaccount.iam.gserviceaccount.com",
                "KeyFileName": "key1.p12",
                "Password": "notasecret"

            },
            {
                "Name": "AnotherAccount",
                "ServiceAccountEmailAddress": "anotherEmailAccount@someotheraccount.iam.gserviceaccount.com",
                "KeyFileName": "key2.p12",
                "Password": "notasecret"

            }
        ],
        "KeyFilePath": "/googleApis/"
    }
}
Run Code Online (Sandbox Code Playgroud)

"GoogleAnalytics"键包含一系列帐户,我希望这些帐户可以作为列表或数组在集合中访问.我创建了一个POCO来表示这个包含相应的'Account'对象集合的密钥:

public class GoogleAnalytics
{
    public Account[] Account { get; set; } = new Account[1];
    public string KeyFilePath { get; set; }

    public GoogleAnalytics()
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

和'帐户'对象:

public class Account
{
    private const string _applicationName = @"Storefront Analytics";
    private X509Certificate2 _certificate;
    private ServiceAccountCredential _credential;
    private AnalyticsService _service;

    #region |--Properties--|

    public string Name { get; set; }
    public string Password { get; set; }
    public string ServiceAccountEmailAddress { get; set; }
    public string KeyFileName { get; set; }
    public string KeyFilePath { get; set; }

    public string KeyFileFullPath
    {
        get
        {
            return $"{KeyFilePath}{KeyFileName}";
        }
    }

    public X509Certificate2 Certificate
    {
        get
        {
            if(_certificate == null)
            {
                ConfigureInstance();
            }

            return _certificate;
        }
        set
        {
            _certificate = value;
        }
    }

    public ServiceAccountCredential Credential
    {
        get
        {
            if (_credential == null)
            {
                ConfigureInstance();
            }

            return _credential;
        }
        set
        {
            _credential = value;
        }
    }

    public AnalyticsService Service
    {
        get
        {
            if (_service == null)
            {
                ConfigureInstance();
            }

            return _service;
        }
        set
        {
            _service = value;
        }
    }

    #endregion

    #region |--Constructors--|

    public Account()
    {

    }

    public Account(string password, string keyFileName, 
       string keyFilePath, 
       string serviceAccountEmailAddress, string accountName)
    {
        //TODO: Validate parameters

        Password = password;
        KeyFileName = keyFileName;
        KeyFilePath = keyFilePath;
        ServiceAccountEmailAddress = serviceAccountEmailAddress;
        Name = accountName;
    }

    #endregion

    private void ConfigureInstance()
    {
        Certificate = new X509Certificate2(KeyFileFullPath, Password, X509KeyStorageFlags.Exportable);

        Credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(ServiceAccountEmailAddress)
        {
            Scopes = new[] { AnalyticsService.Scope.Analytics }
        });

        Service = new AnalyticsService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = Credential,
            ApplicationName = _applicationName
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我的控制器:

public class GoogleAnalyticsController : Controller
{
    #region |--Properties--|

    [FromServices]
    private IGoogleAnalyticsRepository _repo { get; set; }

    #endregion

    public GoogleAnalyticsController(IOptions<GoogleAnalytics> options)
    {
        var temp = options.Value;
    }
}
Run Code Online (Sandbox Code Playgroud)

'KeyFilePath'属性在IOptions实例中正确设置. 在此输入图像描述

我遇到的问题是Account数组包含空引用 - 没有任何帐户被实例化.我想知道我是否做错了,或者选项模型此时不支持这种行为?

更新以回应Shaun Luttin的回答

我在Shaun Luttin的回答中实现了更改列表.似乎还有一个问题.无论出于何种原因,所有Account实例的属性都为null,直到我简化了类,如下所示:

public class Account
{

    public string Name { get; set; }
    public string Password { get; set; }
    public string ServiceAccountEmailAddress { get; set; }
    public string KeyFileName { get; set; }
    public string KeyFilePath { get; set; }

}
Run Code Online (Sandbox Code Playgroud)

Sha*_*tin 5

简答

我想知道我是否做错了,或者选项模型此时不支持这种行为?

你做错了一件事.选项模型支持数组.您不需要使用大小数组初始化数组属性[1].

public Account[] Account { get; set; } = new Account[1];     // wrong
public Account[] Account { get; set; }                       // right
Run Code Online (Sandbox Code Playgroud)

演示

以下是您可以在GitHub上找到的示例.

MyOptions.cs

namespace OptionsExample
{
    public class MyObj
    {
        public string Name { get; set; }
    }

    public class MyOptions
    {
        public string Option1 { get; set; }

        public string[] Option2 { get; set; }

        public MyObj[] MyObj { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

Startup.cs

namespace OptionsExample
{
    using Microsoft.AspNet.Builder;
    using Microsoft.AspNet.Hosting;
    using Microsoft.AspNet.Http;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.OptionsModel;
    using System.Linq;

    public class Startup
    {
        public IConfigurationRoot Config { get; set; }
        public Startup(IHostingEnvironment env)
        {
            Config = new ConfigurationBuilder().AddJsonFile("myoptions.json").Build();
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            services.Configure<MyOptions>(Config);
        }

        public void Configure(IApplicationBuilder app, 
            IOptions<MyOptions> opts)
        {
            app.Run(async (context) =>
            {
                var message = string.Join(",", opts.Value.MyObj.Select(a => a.Name));
                await context.Response.WriteAsync(message);
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

myoptions.json

{
    "option1": "option1val",
    "option2": [
        "option2val1",
        "option2val2",
        "option2val3"
    ],
    "MyObj": [
        {
            "Name": "MyObj1"
        },
        {
            "Name": "MyObj2"
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

project.json依赖项

"dependencies": {
    "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.Extensions.Configuration.Json": "1.0.0-rc1-final"
}
Run Code Online (Sandbox Code Playgroud)

产量

所有选项都存在.