Reputation: 4889
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 is my code above. I got null. How do I get the array?
Upvotes: 396
Views: 274325
Reputation: 509
A different approach that works with objects in .Net Core 7.x
In appsettings.json:
{
"People": [
{ "FirstName": "Glen", "LastName": "Johnson", "Age": 30 },
{ "FirstName": "Matt", "LastName": "Smith", "Age": 40 },
{ "FirstName": "Fred", "LastName": "Williams", "Age": 50 }
]
}
Person class:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
}
And in code:
var appConfig = App.Current.AppConfiguration; // Or could be passed in through DI
var children = appConfig.GetSection("People")
.GetChildren()
.ToList();
var people = new List<Person>();
foreach (var child in children)
{
var rec = new Person
{
FirstName = appConfig[$"{child.Path}:FirstName"],
LastName = appConfig[$"{child.Path}:LastName"],
Age = int.Parse(appConfig[$"{child.Path}:Age"]),
};
people.Add(rec);
}
Upvotes: 0
Reputation: 468
I found this simpler after the IOptions didn't work and much less to do when serializing.
//appsettings.json
"DatabaseModelCreationOptions": {
"Users": [
{
"Id": "1",
"UserName": "adminuser",
"Email": "[email protected]",
"Password": "!Ch4",
"Player": "Admin",
"PlayerInitials": "ADMIN",
"ApiKey": "40753ey"
}
],
"UserRoles": [
{
"Id": "af9986df",
"Name": "Admin",
"ConcurrencyStamp": "ddd53170"
},
{
"Id": "03b82b0e",
"Name": "Manager",
"ConcurrencyStamp": "65da3f89"
}
]
}
Class I needed, I shouldn't need to show you the nested class properties, you can see them above.
public class DatabaseModelCreationOptions
{
public IEnumerable<User>? Users { get; set; }
public IEnumerable<UserRole>? UserRoles { get; set; }
}
Then just invoke GetSection("").Get
var dbOptions = configuration.GetSection("DatabaseModelCreationOptions")
.Get<DatabaseModelCreationOptions>();
Upvotes: 4
Reputation: 414
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));
}
}
Upvotes: 5
Reputation: 676
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/"
Upvotes: 1
Reputation: 749
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>>();
Upvotes: 33
Reputation: 11
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;
Upvotes: 1
Reputation: 12472
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[]>();
Upvotes: 684
Reputation: 1732
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:
Upvotes: 1
Reputation: 59
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;
Upvotes: 4
Reputation: 380
public class MyArray : List<string> { }
services.Configure<ShipmentDetailsDisplayGidRoles>(Configuration.GetSection("MyArray"));
public SomeController(IOptions<MyArray> myArrayOptions)
{
myArray = myArrayOptions.Value;
}
Upvotes: 4
Reputation: 1083
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);
Upvotes: 7
Reputation: 13272
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'.
Upvotes: 19
Reputation: 448
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[]>();
Upvotes: 18
Reputation: 9391
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 :)
Upvotes: 94
Reputation: 568
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"}
Upvotes: 6
Reputation: 749
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" ]
}
}
Upvotes: 51
Reputation: 20037
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.
Upvotes: 202
Reputation: 3111
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 };
}
Upvotes: 27
Reputation: 91
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"));
//...
}
Upvotes: 9
Reputation: 28320
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");
}
Upvotes: 81