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

时间:2016-02-18 15:54:16

标签: json asp.net-core configuration-files appsettings

我正在使用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/"
    }
}

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

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

    public GoogleAnalytics()
    {

    }
}

和'帐户'对象:

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
        });
    }
}

我的控制器:

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

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

    #endregion

    public GoogleAnalyticsController(IOptions<GoogleAnalytics> options)
    {
        var temp = options.Value;
    }
}

在“IOptions”实例中正确设置了“KeyFilePath”属性。 enter image description here

我遇到的问题是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; }

}

1 个答案:

答案 0 :(得分:5)

简答

  

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

你做错了。选项模型确实支持数组。您无需使用大小为[1]的数组初始化数组属性。

public Account[] Account { get; set; } = new Account[1];     // wrong
public Account[] Account { get; set; }                       // right

演示

以下是一个示例,仅供您参考,您可以找到here on 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; }
    }
}

<强> 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);
            });
        }
    }
}

<强> myoptions.json

{
    "option1": "option1val",
    "option2": [
        "option2val1",
        "option2val2",
        "option2val3"
    ],
    "MyObj": [
        {
            "Name": "MyObj1"
        },
        {
            "Name": "MyObj2"
        }
    ]
}

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"
}

<强>输出

All options are present.