'ASP.NET Core Get Json Array using IConfiguration

In appsettings.json

{
      "MyArray": [
          "str1",
          "str2",
          "str3"
      ]
}

In Startup.cs

public void ConfigureServices(IServiceCollection services)
{
     services.AddSingleton<IConfiguration>(Configuration);
}

In HomeController

public class HomeController : Controller
{
    private readonly IConfiguration _config;
    public HomeController(IConfiguration config)
    {
        this._config = config;
    }

    public IActionResult Index()
    {
        return Json(_config.GetSection("MyArray"));
    }
}

There are my codes above, I got null How to get the array?



Solution 1:[1]

If you want to pick value of first item then you should do like this-

var item0 = _config.GetSection("MyArray:0");

If you want to pick value of entire array then you should do like this-

IConfigurationSection myArraySection = _config.GetSection("MyArray");
var itemArray = myArraySection.AsEnumerable();

Ideally, you should consider using options pattern suggested by official documentation. This will give you more benefits.

Solution 2:[2]

You can install the following two NuGet packages:

using Microsoft.Extensions.Configuration; 
using Microsoft.Extensions.Configuration.Binder;

And then you'll have the possibility to use the following extension method:

var myArray = _config.GetSection("MyArray").Get<string[]>();

Solution 3:[3]

Add a level in your appsettings.json :

{
  "MySettings": {
    "MyArray": [
      "str1",
      "str2",
      "str3"
    ]
  }
}

Create a class representing your section :

public class MySettings
{
     public List<string> MyArray {get; set;}
}

In your application startup class, bind your model an inject it in the DI service :

services.Configure<MySettings>(options => Configuration.GetSection("MySettings").Bind(options));

And in your controller, get your configuration data from the DI service :

public class HomeController : Controller
{
    private readonly List<string> _myArray;

    public HomeController(IOptions<MySettings> mySettings)
    {
        _myArray = mySettings.Value.MyArray;
    }

    public IActionResult Index()
    {
        return Json(_myArray);
    }
}

You can also store your entire configuration model in a property in your controller, if you need all the data :

public class HomeController : Controller
{
    private readonly MySettings _mySettings;

    public HomeController(IOptions<MySettings> mySettings)
    {
        _mySettings = mySettings.Value;
    }

    public IActionResult Index()
    {
        return Json(_mySettings.MyArray);
    }
}

The ASP.NET Core's dependency injection service works just like a charm :)

Solution 4:[4]

If you have array of complex JSON objects like this:

{
  "MySettings": {
    "MyValues": [
      { "Key": "Key1", "Value":  "Value1" },
      { "Key": "Key2", "Value":  "Value2" }
    ]
  }
}

You can retrieve settings this way:

var valuesSection = configuration.GetSection("MySettings:MyValues");
foreach (IConfigurationSection section in valuesSection.GetChildren())
{
    var key = section.GetValue<string>("Key");
    var value = section.GetValue<string>("Value");
}

Solution 5:[5]

This worked for me to return an array of strings from my config:

var allowedMethods = Configuration.GetSection("AppSettings:CORS-Settings:Allow-Methods")
    .Get<string[]>();

My configuration section looks like this:

"AppSettings": {
    "CORS-Settings": {
        "Allow-Origins": [ "http://localhost:8000" ],
        "Allow-Methods": [ "OPTIONS","GET","HEAD","POST","PUT","DELETE" ]
    }
}

Solution 6:[6]

DotNet Core 3.1:

Json config:

"TestUsers": 
{
    "User": [
    {
      "UserName": "TestUser",
      "Email": "[email protected]",
      "Password": "P@ssw0rd!"
    },
    {
      "UserName": "TestUser2",
      "Email": "[email protected]",
      "Password": "P@ssw0rd!"
    }]
}

Then create a User.cs class with auto properties that corresponds to User objects in the Json config above. Then you can reference Microsoft.Extensions.Configuration.Abstractions and do:

List<User> myTestUsers = Config.GetSection("TestUsers").GetSection("User").Get<List<User>>();

Solution 7:[7]

For the case of returning an array of complex JSON objects from configuration, I've adapted @djangojazz's answer to use anonymous types and dynamic rather than tuples.

Given a settings section of:

"TestUsers": [
{
  "UserName": "TestUser",
  "Email": "[email protected]",
  "Password": "P@ssw0rd!"
},
{
  "UserName": "TestUser2",
  "Email": "[email protected]",
  "Password": "P@ssw0rd!"
}],

You can return the object array this way:

public dynamic GetTestUsers()
{
    var testUsers = Configuration.GetSection("TestUsers")
                    .GetChildren()
                    .ToList()
                    .Select(x => new {
                        UserName = x.GetValue<string>("UserName"),
                        Email = x.GetValue<string>("Email"),
                        Password = x.GetValue<string>("Password")
                    });

    return new { Data = testUsers };
}

Solution 8:[8]

In ASP.NET Core 2.2 and later we can inject IConfiguration anywhere in our application like in your case, you can inject IConfiguration in HomeController and use like this to get the array.

string[] array = _config.GetSection("MyArray").Get<string[]>();

Solution 9:[9]

Kind of an old question, but I can give an answer updated for .NET Core 2.1 with C# 7 standards. Say I have a listing only in appsettings.Development.json such as:

"TestUsers": [
  {
    "UserName": "TestUser",
    "Email": "[email protected]",
    "Password": "P@ssw0rd!"
  },
  {
    "UserName": "TestUser2",
    "Email": "[email protected]",
    "Password": "P@ssw0rd!"
  }
]

I can extract them anywhere that the Microsoft.Extensions.Configuration.IConfiguration is implemented and wired up like so:

var testUsers = Configuration.GetSection("TestUsers")
   .GetChildren()
   .ToList()
    //Named tuple returns, new in C# 7
   .Select(x => 
         (
          x.GetValue<string>("UserName"), 
          x.GetValue<string>("Email"), 
          x.GetValue<string>("Password")
          )
    )
    .ToList<(string UserName, string Email, string Password)>();

Now I have a list of a well typed object that is well typed. If I go testUsers.First(), Visual Studio should now show options for the 'UserName', 'Email', and 'Password'.

Solution 10:[10]

You can get the array direct without increment a new level in the configuration:

public void ConfigureServices(IServiceCollection services) {
    services.Configure<List<String>>(Configuration.GetSection("MyArray"));
    //...
}

Solution 11:[11]

This worked for me; Create some json file:

{
    "keyGroups": [
        {
            "Name": "group1",
            "keys": [
                "user3",
                "user4"
            ]
        },
        {
            "Name": "feature2And3",
            "keys": [
                "user3",
                "user4"
            ]
        },
        {
            "Name": "feature5Group",
            "keys": [
                "user5"
            ]
        }
    ]
}

Then, define some class that maps:

public class KeyGroup
{
    public string name { get; set; }
    public List<String> keys { get; set; }
}

nuget packages:

Microsoft.Extentions.Configuration.Binder 3.1.3
Microsoft.Extentions.Configuration 3.1.3
Microsoft.Extentions.Configuration.json 3.1.3

Then, load it:

using Microsoft.Extensions.Configuration;
using System.Linq;
using System.Collections.Generic;

ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();

configurationBuilder.AddJsonFile("keygroup.json", optional: true, reloadOnChange: true);

IConfigurationRoot config = configurationBuilder.Build();

var sectionKeyGroups = 
config.GetSection("keyGroups");
List<KeyGroup> keyGroups = 
sectionKeyGroups.Get<List<KeyGroup>>();

Dictionary<String, KeyGroup> dict = 
            keyGroups = keyGroups.ToDictionary(kg => kg.name, kg => kg);

Solution 12:[12]

Short form:

var myArray= configuration.GetSection("MyArray")
                        .AsEnumerable()
                        .Where(p => p.Value != null)
                        .Select(p => p.Value)
                        .ToArray();

It returns an array of string:

{"str1","str2","str3"}

Solution 13:[13]

public class MyArray : List<string> { }

services.Configure<ShipmentDetailsDisplayGidRoles>(Configuration.GetSection("MyArray"));

public SomeController(IOptions<MyArray> myArrayOptions)
{
    myArray = myArrayOptions.Value;
}

Solution 14:[14]

appsettings.json:

"MySetting": {
  "MyValues": [
    "C#",
    "ASP.NET",
    "SQL"
  ]
},

MySetting class:

namespace AspNetCore.API.Models
{
    public class MySetting : IMySetting
    {
        public string[] MyValues { get; set; }
    }

    public interface IMySetting
    {
        string[] MyValues { get; set; }
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.Configure<MySetting>(Configuration.GetSection(nameof(MySetting)));
    services.AddSingleton<IMySetting>(sp => sp.GetRequiredService<IOptions<MySetting>>().Value);
    ...
}

Controller.cs

public class DynamicController : ControllerBase
{
    private readonly IMySetting _mySetting;

    public DynamicController(IMySetting mySetting)
    {
        this._mySetting = mySetting;
    }
}

Access values:

var myValues = this._mySetting.MyValues;

Solution 15:[15]

To get all values of all sections from appsettings.json

        public static string[] Sections = { "LogDirectory", "Application", "Email" };
        Dictionary<string, string> sectionDictionary = new Dictionary<string, string>();

        List<string> sectionNames = new List<string>(Sections);
        
        sectionNames.ForEach(section =>
        {
            List<KeyValuePair<string, string>> sectionValues = configuration.GetSection(section)
                    .AsEnumerable()
                    .Where(p => p.Value != null)
                    .ToList();
            foreach (var subSection in sectionValues)
            {
                sectionDictionary.Add(subSection.Key, subSection.Value);
            }
        });
        return sectionDictionary;

Solution 16:[16]

setting.json file:

{
    "AppSetting": {
        "ProfileDirectory": "C:/Users/",
        "Database": {
            "Port": 7002
        },
        "Backend": {
            "RunAsAdmin": true,
            "InstallAsService": true,
            "Urls": [
                "http://127.0.0.1:8000"
            ],
            "Port": 8000,
            "ServiceName": "xxxxx"
        }
    }
}

code

code:

public static IConfigurationRoot GetConfigurationFromArgs(string[] args, string cfgDir)
{
    var builder = new ConfigurationBuilder()
            .SetBasePath(cfgDir)
            .AddCommandLine(args ?? new string[0]) // null  in UnitTest null will cause exception
            .AddJsonFile(Path.Combine(cfgDir, "setting.json"), optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
        // .AddInMemoryollection(configDictionary)
        ;
    var config = builder.Build();
    return config;
}

you can use services.AddOptions<AppSettingOption>("AppSetting") or directly get Object from IConfigurationRoot object.

var cfg = GetConfigurationFromArgs(args, appDataDirectory);
cfg.GetSection("AppSetting").Get<AppSettingOption>()

Output:

{App.AppSettingOption}
    Backend: {App.BackendOption}
    Database: {App.DatabaseOption}
    ProfileDirectory: "C:/Users/"

Solution 17:[17]

You can use Microsoft.Extensions.Configuration.Binder package like this:

In your appsettings.json

{
      "MyArray": [
          "str1",
          "str2",
          "str3"
      ]
}

Create your object to hold your configuration:

 public class MyConfig
 {
     public List<string> MyArray { get; set; }
 }

And in you controller Bind the config:

public class HomeController : Controller
{
    private readonly IConfiguration _config;
    private readonly MyConfig _myConfig = new MyConfig();

    public HomeController(IConfiguration config)
    {
        _config = config;
    }

    public IActionResult Index()
    {
        return Json(_config.Bind(_myConfig));
    }
}

Solution 18:[18]

Recently I also had a need to read a simple array of strings from an appsettings.json file (and other similar .json configuration files).

For my approach, I created a simple extension method that does the trick:

public static class IConfigurationRootExtensions
{
    public static string[] GetArray(this IConfigurationRoot configuration, string key)
    {
        var collection = new List<string>();
        var children = configuration.GetSection(key)?.GetChildren();
        if (children != null)
        {
            foreach (var child in children) collection.Add(child.Value);
        }
        return collection.ToArray();
    }
}

The original poster's .json file looked as follows:

{
      "MyArray": [
          "str1",
          "str2",
          "str3"
      ]
}

Using the above extension method, it makes reading this array a very simple one-line affair, as seen in the following example:

var configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
string[] values = configuration.GetArray("MyArray");

At runtime, setting a breakpoint with a 'QuickWatch' on values verifies that we have successfully read the values from the .json configuration file into a string array:

QuickWatch on values context