t.j. t.j. - 1 month ago 8
ASP.NET (C#) Question

asp5 IConfigurationRoot get json array

I am trying to supply some additional configuration data to my asp 5 mvc 6 web app ("rc1-final" libraries) to be deployed on Azure. Part of this additional data consists of an array of data in a json file. I can add this json file to my configuration, and while debugging if I watch the configuration object I can browse to the provider entry and see it does in fact contact the array of data I'm looking for.

However, trying

Configuration["extraData"]
yields null (as the "value" of that property is null, even though it clearly contains the array of elements.

I have no problem accessing single values that are stored in json config (such as my database connection string, and other values.) It just seems as though json data in array format is not supported?

See the following sample json file (which validates according to jsonlint and seems fine to me)...

//extraData.json
{
"ExtraData": [
{
"Id": 1,
"Description": "The first identifier"
},
{
"Id": 2,
"Description": "The second identifier"
},
{
"Id": 3,
"Description": "The third identifier"
}
]
}


...and the following sample 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; }
}
}


What I've been having to do instead (which seems hackish, especially given the handy Configuration system now available)...

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


I'm also uncertain as to the support on azure to do file io like this.

I found this resource which suggests that array/IEnum is supported, but it is just using an in-mem provider...

http://github.com/aspnet/Configuration/blob/dev/test/Microsoft.Extensions.Configuration.Binder.Test/ConfigurationCollectionBindingTests.cs

This resource is the documentation from MS...

http://docs.asp.net/en/latest/fundamentals/configuration.html

Some related questions that have turned up while searching since posted (not 1:1 related to my issue necessarily, but could prove useful for others searching)

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

Answer

try this out:

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