我正在尝试向我的asp 5 mvc 6 web应用程序(“rc1-final”库)提供一些额外的配置数据,以便部署在Azure上。此附加数据的一部分由json文件中的数据数组组成。我可以将这个json文件添加到我的配置中,并且在调试时如果我观察配置对象,我可以浏览到提供者条目,看到它确实联系了我正在寻找的数据数组。
但是,尝试Configuration["extraData"]
会产生null(因为该属性的“值”为null,即使它显然包含元素数组。
访问存储在json配置中的单个值(例如我的数据库连接字符串和其他值)没有问题。看起来好像不支持数组格式的json数据?
请参阅以下示例json文件(根据jsonlint进行验证,对我来说似乎很好)...
//extraData.json
{
"ExtraData": [
{
"Id": 1,
"Description": "The first identifier"
},
{
"Id": 2,
"Description": "The second identifier"
},
{
"Id": 3,
"Description": "The third identifier"
}
]
}
...以及以下示例Startup.cs ...
//Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Data.Entity;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Linq;
using System.IO;
using Microsoft.AspNet.Authentication.Cookies;
using System.Net;
namespace MyProj {
public class Startup {
public static IConfigurationRoot Configuration;
public Startup(IHostingEnvironment env) {
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile("extraData.json")
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public void Configure(
IApplicationBuilder app,
IHostingEnvironment env,
MyDbSeed seed,
ILoggerFactory logging) {
dynamic xData = JObject.Parse("ExtraData"); //VALUE IS NULL, THROWS EX
var myList = JsonConvert
.DeserializeObject<List<MyID>>(
xData.ExtraData.ToString()
);
//Do something important with this list
}
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
class MyID {
public int ID { get; set; }
public string Description { get; set; }
}
}
我不得不做的事情(这看起来很神圣,特别是考虑到现在可用的配置系统)......
dynamic xData = JObject.Parse(
File.OpenText(
env.MapPath(
@"..\extraData.json"
)
).ReadToEnd()
);
var xList = JsonConvert
.DeserializeObject<List<MyID>>(
xData.ExtraData.ToString()
);
//Do something important with the list, eg...
var o = new MyClass(xList);
我也不确定azure的支持就像这样做文件io。
我发现这个资源表明支持array / IEnum,但它只是使用内存提供程序...
http://github.com/aspnet/Configuration/blob/dev/test/Microsoft.Extensions.Configuration.Binder.Test/ConfigurationCollectionBindingTests.cs
此资源是来自MS的文档...
http://docs.asp.net/en/latest/fundamentals/configuration.html
自发布以来搜索时出现的一些相关问题(不是1:1与我的问题有关,但可能对其他搜索有用)
How to use ConfigurationBinder in Configure method of startup.cs
Retrieve sections from config.json in ASP.NET 5
ASP.NET 5 (vNext) - Getting a Configuration Setting
答案 0 :(得分:19)
我们现在可以使用GetSection
和GetChildren
以及一些LINQ。
// appsettings.json
{
"SomeArray": [
"Foo",
"Bar",
"Baz"
]
}
// Startup.cs
var someArray = configuration
.GetSection("SomeArray")
.GetChildren()
.Select(x => x.Value)
.ToArray();
答案 1 :(得分:9)
试试这个:
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.OptionsModel;
using System.Collections.Generic;
namespace WebApplication1
{
public class Startup
{
public Startup(IHostingEnvironment env)
{
// Set up configuration sources.
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddJsonFile("extraData.json")
.AddEnvironmentVariables();
Configuration = builder.Build();
}
public IConfigurationRoot Configuration { get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<List<ExtraData>>(Configuration.GetSection("ExtraData"));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
List<ExtraData> result = app.ApplicationServices.GetRequiredService<IOptions<List<ExtraData>>>().Value;
// you should get what you need. It works in my computer with rc1 update 1
}
public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}
public class ExtraData
{
public int Id { get; set; }
public string Description { get; set; }
}
}
修改强>
如果编译器抱怨services.Configure<List<ExtraData>>(Configuration.GetSection("ExtraData"))
,请添加一个NuGet引用Microsoft.Extensions.Options.ConfigurationExtensions
您也可以将它注入构造函数:
// using Microsoft.Extensions.Options;
public class HomeController : Controller
{
private List<ExtraData> _extraData;
public HomeController(IOptions<List<ExtraData>> extraData)
{
_extraData = extraData.Value;
}
}
答案 2 :(得分:5)
您可以通过以下方式检索设置:
var extraDataSection = configuration.GetSection("ExtraData");
foreach (IConfigurationSection section in extraDataSection.GetChildren())
{
var id = section.GetValue<int>("Id");
var description = section.GetValue<string>("Description");
}
答案 3 :(得分:1)
使用最新版本,我无需任何额外的NuGet包即可解决此问题:
int extraDataCount = 0;
string id = Configuration[GetId(extraDataCount)];
string description = Configuration[GetDescription(extraDataCount)];
var extraDataList = new List<MyID>();
while(id != null && description != null)
{
extraDataList.Add(new MyID { ID = id, Description = description });
extraDataCount++;
id = Configuration[GetId(extraDataCount)];
description = Configuration[GetDescription(extraDataCount)];
}
private string GetId(int extraDataCount)
{
return "ExtraData:" + extraDataCount + ":Id";
}
private string GetDescription(int extraDataCount)
{
return "ExtraData:" + extraDataCount + ":Description";
}