I currentying trying to save the api url in an appsettings.
However, the configuration.Propertiers seems to be empty. I am not sure how to get the setting.
in program.cs:
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
//string url = builder.Configuration.Properties["APIURL"].ToString();
foreach (var prop in builder.Configuration.Properties)
Console.WriteLine($"{prop.Key} : {prop.Value}" );
//builder.Services.AddSingleton<Service>(new Service(url));
builder.RootComponents.Add<App>("app");
await builder.Build().RunAsync();
}
Inkkiller nailed it. You can simplify the call into IConfiguration without the APIHelper class and access it directly in Program.cs from the WebAssemblyHostBuilder.
appsettings:
{
"ServerlessBaseURI": "http://localhost:0000/",
}
Program.cs:
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
string serverlessBaseURI = builder.Configuration["ServerlessBaseURI"];
}
This answer concerned blazor preview when blazor didn't support appsettings.json in wwwroot folder yet. You should use appsettings.json in wwroot folder now and WebAssemblyHostBuilder.Configuration. It also support per environment files (appsettings.{env}.Json).
I solve this issue by using a settings.json file store in the app wwwroot folder and register a task to get the settings :
Settings.cs
public class Settings
{
public string ApiUrl { get; set; }
}
wwwroot/settings.json
{
"ApiUrl": "https://localhost:51443/api"
}
Progam.cs
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Services.AddSingleton(async p =>
{
var httpClient = p.GetRequiredService<HttpClient>();
return await httpClient.GetJsonAsync<Settings>("settings.json")
.ConfigureAwait(false);
});
SampleComponent.razor
#inject Task<Settings> getsettingsTask
#inject HttpClient client
...
#code {
private async Task CallApi()
{
var settings = await getsettingsTask();
var response = await client.GetJsonAsync<SomeResult>(settings.ApiUrl);
}
}
This has advantages:
Doesn't share the server's appsettings.json file which can be a security hole
Configurable per environment
Using ASP.NET Core 6.0 Blazor configuration. Blazor WebAssembly loads configuration from the following app settings files by default:
wwwroot/appsettings.json.
wwwroot/appsettings.{ENVIRONMENT}.json, where the {ENVIRONMENT}
placeholder is the app's runtime environment.
Example:
wwwroot/appsettings.json
{
"h1FontSize": "50px"
}
Pages/ConfigurationExample.razor
#page "/configuration-example"
#using Microsoft.Extensions.Configuration
#inject IConfiguration Configuration
<h1 style="font-size:#Configuration["h1FontSize"]">
Configuration example
</h1>
Warning Configuration and settings files in a Blazor WebAssembly app
are visible to users. Don't store app secrets, credentials, or any
other sensitive data in the configuration or files of a Blazor
WebAssembly app.
https://learn.microsoft.com/en-us/aspnet/core/blazor/fundamentals/configuration?view=aspnetcore-6.0
You can also bind the values to a class.
public class ClientAppSettings
{
public string h1FontSize{ get; set; }
}
Then add this class as a Singleton in Program.cs:
var settings = new ClientAppSettings();
builder.Configuration.Bind(settings);
builder.Services.AddSingleton(settings);
Add namespace to _Imports.razor and then inject where needed to get settings with autocomplete in Visual Studio:
#inject ClientAppSettings ClientAppSettings
You can also just (appsettings.json in wwwroot):
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
var url = builder.Configuration.GetValue<string>("ApiConfig:Url");
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(url) });
}
}
As of now, you can use the IConfiguration.
appsettings.json:
{
"Services": {
"apiURL": "https://localhost:11111/"
}
}
.
using Microsoft.Extensions.Configuration;
public class APIHelper
{
private string apiURL;
public APIHelper(IConfiguration config)
{
apiURL = config.GetSection("Services")["apiURL"];
//Other Stuff
}
}
Blazor WASM appsettings.json
If you dont have appsettings.json in the wwwroot folder then simply:
Right click on wwwroot folder.
Click Add ==> New Item ==> App Settings File
This will add appsettings.json to your application. Open the appsettings.json file you will see a section in it already for database add a section like I have added apiinfo:
{
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;MultipleActiveResultSets=true"
},
"apiinfo":{
"apiurl": "your api url"
}
}
Now when you want to call this section simply Inject configuration and call it like:
#inject Microsoft.Extensions.Configuration.IConfiguration config;
And to call the apiurl:
config.GetSection("apiinfo")["apiurl"].ToString()
as an example, I have it implemeneted like this (client-side Blazor):
appsettings.json:
{
"api": "https://www.webapiurl.com/"
"ForceHTTPS": false
}
then, have typed config class
public class APISetting
{
public string api { get; set; }
public bool ForceHTTPS { get; set; }
}
then, load on startup:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(GetConfiguration());
}
public void Configure(IComponentsApplicationBuilder app )
{
app.AddComponent<App>("app");
}
public APISetting GetConfiguration()
{
using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("appsettings.json"))
using (var reader = new System.IO.StreamReader(stream))
{
return System.Text.Json.JsonSerializer.Deserialize<APISetting>(reader.ReadToEnd());
}
}
}
Also in .Net 5 & 6 you can set the value to Static Class.
Example:
wwwroot/appsettings.json
"ServicesUrlOptions": {
"Url": "https://domain.gr/services" }
Static Class
public static class ApplicationServicesSettings
{
public const string ServicesUrl = "ServicesUrlOptions";
public static ServicesUrlOptions ServicesUrlOptions { get; set; } = new ServicesUrlOptions();
}
public class ServicesUrlOptions
{
public string Url { get; set; }
}
Finally bind the value at Program.cs
builder.Configuration.GetSection(ApplicationServicesSettings.ServicesUrl).Bind(ApplicationServicesSettings.ServicesUrlOptions);
After in project you have access to key by
ApplicationServicesSettings.ServicesUrlOptions.Url
create settings class:
public class Settings
{
public string ApiUrl { get; set; }
}
create settings.json in wwwroot folder:
{
"ApiUrl": "http://myapiurlhere"
}
and in .razor component read it like this:
#inject HttpClient Http
...
#code {
private string WebApuUrl = "";
protected override async Task OnInitializedAsync()
{
var response = await Http.GetFromJsonAsync<Settings>("settings.json");
WebApuUrl = response.ApiUrl;
}
}
Related
I want to read appsettings.json non-controller class.Consider has a DatabaseUtil and contain a static connect() method. I need to connectionString for connection and i'm getting this from appsettings.json.This operation piece of cake in the startup.cs:)
Like this:
Configuration.GetConnectionString("HangfireDBConn")
Also it can be at the controller side with dependcy injection.But my problem which want to reach appSettings from DatbaseUtil class.
appSettings.json:
"NotifySettings": {
"DbConnection": "abc",
"Email": "abc#domain.com",
"SMTPPort": "5605"
}
Then i created my configuration settings class:
public class NotifySettings
{
public string DbConnection { get; set; }
public string Email { get; set; }
public string SMTPPort { get; set; }
}
And I added dependency for constructor injection to DatabaseUtil class and added IDatabaseUtil
public class DatabaseUtil : IDatabaseUtil
{
private static NotifySettings _NotifySettings;
public DatabaseUtil(IConfiguration _iconfig)
{
_NotifySettings = _iconfig.GetSection("NotifySettings").Get<NotifySettings>();
}
public static String ConnectToDatabase()
{
return "MESSAGE :" + _NotifySettings.DbConnection;
}
}
}
And i added DatabaseUtil to startup.cs
services.AddScoped<IDatabaseUtil, DatabaseUtil>();
and finally i injected IDatabaseUtil to my controller class and i can reach mysettings end of the this work.
Yes i can but not best way!
Let the join my Brain Storming :) ; If i have to inject to IDatabaseUtil every class where i want to use db helper methods.But if i had a static method in this class just it need to this line of code:
DatabaseUtils.connect();
That's feels me like i wrote unnecessary code.
What do you think about my approximation.Which one is best way for this case ?
change
services.AddScoped<IDatabaseUtil, DatabaseUtil>();
to
services.AddSingleton<IDatabaseUtil, DatabaseUtil>();
This way you only have one instance of DatabaseUtil
I'm still not entirely clear, but if the need here is to make values from your Configuration statically available, then copy them from your configuration to a static class during the startup:
public static class GlobalSettings
{
public static string ConnectionString { get; set; }
}
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
GlobalSettings.ConnectionString = Configuration.GetSection("ConnectionString").Value;
// ...
}
}
If you need to get the config and do the assignment from somewhere else, use the ConfigurationBuilder:
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
using System;
using Microsoft.Extensions.Configuration;
namespace project.Utility
{
public class ConnectionString
{
private IConfigurationRoot _config;
private static ConnectionString _internalInstance;
public static ConnectionString Instance
{
get
{
return _internalInstance;
}
}
public static void Init(IConfigurationRoot config)
{
_internalInstance = new ConnectionString();
_internalInstance._config = config;
}
public String Get(string key)
{
var NotifySettings =
Instance._config.GetSection(key).Get<NotifySettings>();;
return NotifySettings;
}
}
}
// call this above method from any place like controller or class file by below code
// use refernece of the namespace
ConnectionString connectionString = new ConnectionString(); // object creation
NotifySettings settings = connectionString.Get("NotifySettings"); // call with your key value get the settings object
Try this it should work let me know if any issues i can help on that
I'm using .net core 3.1 to build a console app that acts as an event handler API.
The app captures changes to a database and directs those changes to other APIs, in real-time. Updates to "customer" go to "customerAPI", "product" goes to "productAPI" and so on. This means that I have an appsettings.Local.json that looks like this:
"DBConnectionStrings": {
"DefaultConnection": "AccountEndpoint=(my account)",
"SourceDatabaseName": "MyDB",
"SourceContainerName": "MySource",
"LeasesContainerName": "MyLease",
"PartitionKey": "/id"
},
"EndpointAPIStrings": {
"Endpoint1": {
"EndpointUrl": "https://localhost:7777",
"Username": "myusername1",
"Password": "mypassword1",
"Endpoint2": {
"EndpointUrl": "https://localhost:8888",
"Username": "myusername2",
"Password": "mypassword2",
"Endpoint3": {
"EndpointUrl": "https://localhost:9999",
"Username": "myusername3",
"Password": "mypassword3"
...
}
I am currently using a crappy method of declaring them as EnvironmentVariables to get them from my Main where the configuration is built to my CallAPI Task.
Main:
public static async Task Main(string[] args)
{
...
IConfiguration configuration = BuildConfiguration(environmentName);
CosmosClient cosmosClient = BuildCosmosClient(configuration);
Environment.SetEnvironmentVariable("EndpointUrl", configuration["EndpointAPIStrings:Endpoint1:EndpointURL"]);
Environment.SetEnvironmentVariable("Username", configuration["EndpointAPIStrings:Endpoint1:Username"]);
Environment.SetEnvironmentVariable("Password", configuration["EndpointAPIStrings:Endpoint1:Password"]);
...
}
Delegate function:
...
if (entityType == "myproduct")
{
var entity = "products";
var result = await Task.Run(() => CallAPIAsync(entity, item));
}
...
Task CallAPI:
public static async Task<HttpResponseMessage> CallAPIAsync(string entity, ProcessedItem item)
{
using (var client = new HttpClient())
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
var endpointUrl = Environment.GetEnvironmentVariable("EndpointUrl");
var uri = new Uri($"{endpointUrl}/api/{entity}/{item.Id}/propagate");
string username = Environment.GetEnvironmentVariable("Username");
string password = Environment.GetEnvironmentVariable("Password");
...
}
}
This obviously only works for the first endpoint and ignores the others.
How can I refactor this to get the values into my CallAPI Task for all EndpointAPIStrings?
I've done this in a Windows Service .net Core 3.1 app, pretty similar. Essentially when you call your IHostBuilder function in program.cs
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureLogging(loggerFactory => loggerFactory.AddEventLog())
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
});
You get access to your configuration variables from appsettings.json by default. Which can then be accessed in your main startup or execute function:
private readonly ILogger<Worker> _logger;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IConfiguration _config;
public Worker(ILogger<Worker> logger, IServiceScopeFactory serviceScopeFactory, IConfiguration config)
{
_logger = logger;
_serviceScopeFactory = serviceScopeFactory;
_config = config;
}
And then in your main or execute function:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// Must be a scoped process in order to run correctly
using var scope = _serviceScopeFactory.CreateScope();
// Start timer and begin log
var startTime = DateTime.UtcNow;
var env = _config.GetValue<string>("ENV");
var stageTable = _config.GetValue<string>("StageTable");
var prevTable = _config.GetValue<string>("PrevTable");
var mainTable = _config.GetValue<string>("MainTable");
var sqlConnectionString = _config.GetValue<string>("SqlConnString_" + env);
var excelConnectionString = _config.GetValue<string>("ExcelConnectionString1") +
_config.GetValue<string>("ExcelFilePath_" + env) +
_config.GetValue<string>("ExcelFileName") +
_config.GetValue<string>("ExcelConnectionString2");
With an appsettings.json like:
"ENV": "LOCAL",
"StageTable": "Staging",
"PrevTable": "Previous",
"MainTable": "Courses",
You can create a class for it and read the values into that class. Also changing it to a list in the JSON would be good. Steps I would do:
Change 'EndpointAPIStrings' into an array:
{
"EndpointAPIStrings":[
{
"Id":"Endpoint1",
"EndpointUrl":"https://localhost:7777",
"Username":"myusername1",
"Password":"mypassword1"
},
{
"Id":"Endpoint2",
"EndpointUrl":"https://localhost:8888",
"Username":"myusername2",
"Password":"mypassword2"
},
{
"Id":"Endpoint3",
"EndpointUrl":"https://localhost:9999",
"Username":"myusername3",
"Password":"mypassword3"
}
]
}
Create a C# class defining the objects in the JSON array:
public sealed class EndPoint {
public string Id { get; set; }
public string EndPointUrl { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
Change data retrieval from the configuration:
IConfiguration configuration = BuildConfiguration(environmentName);
CosmosClient cosmosClient = BuildCosmosClient(configuration);
List<EndPoint> endPoints = configuration.GetSection("EndPointAPIStrings").Get<List<EndPoint>>();
Now you have all your endpoints in the endPoints variable. You can remove and add properties into the JSON how you like and the only thing you need to do is change the class accordingly. Please note that you need the same names in the JSON and in the C# class in order to get a successful mapping.
I am trying to have some basic configuration from json file to a singleton service inside my client side blazor application at the start up.
Below is my code setup
AppConfig and IAppConfig files
interface IAppConfig
{
string BaseUrl { get; set; }
string Source { get; set; }
}
and
public class AppConfig : IAppConfig
{
public string BaseUrl { get; set; }
public string Source { get; set; }
}
Than a json file by the name of environment.json inside wwwroot as wwwroot/ConfigFiles/environment.json
Than a service to read this file
interface ISharedServices
{
Task<AppConfig> GetConfigurationAsync();
}
and
public class SharedServices : ISharedServices
{
private HttpClient Http { get; set; }
public SharedServices(HttpClient httpClient)
{
Http = httpClient;
}
public async Task<AppConfig> GetConfigurationAsync()
{
return await Http.GetJsonAsync<AppConfig>("ConfigFiles/environment.json");
}
}
Now i am calling it into my component which load first
public class IndexComponent : ComponentBase
{
[Inject]
internal IAppConfig AppConfig { get; set; }
[Inject]
internal ISharedServices sharedServices { get; set; }
protected override async Task OnInitializedAsync()
{
var appconfig = await sharedServices.GetConfigurationAsync();
AppConfig = appconfig;
}
}
All this works fine , but i want to have this configuration ready at the time of application load in browser , so as suggested by "auga from mars" in my other Question i tried below code inside startup.cs at the moment i add IAppConfig as singleton service
services.AddSingleton<IAppConfig, AppConfig>(provider =>
{
var http = provider.GetRequiredService<HttpClient>();
return http.GetJsonAsync<AppConfig>("ConfigFiles/environment.json").GetAwaiter().GetResult();
});
But , buy using this code the blazor app never start up , all it show a blank white page with text Loading.... , not even any error but in every 5 min pop up show - page taking too much time to load with two option of wait and close .
If i change this code a bit from
return http.GetJsonAsync<AppConfig>("ConfigFiles/environment.json").GetAwaiter().GetResult();
to
return http.GetJsonAsync<AppConfig>("ConfigFiles/environment.json").Result;
Than it say - "Maximum call stack size exceed"
How to have configuration ready at startup ??
Update 1:
A little Update
in Basecomponent file , code is
protected override async Task OnInitializedAsync()
{
var appconfig = await sharedServices.GetConfigurationAsync();
AppConfig.BaseUrl = appconfig.BaseUrl;
AppConfig.Source = appconfig.Source;
}
I have to set every property one by one manually , need to get rid of this too
I have a new Asp.Net core application that has the following entry in the appsettings.json file:
{
"DatabaseConnections": {
"DatabaseUri": "https://localhost:8081",
"ApplicationKey": "C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==",
"DatabaseName": "MyDatabase"
}
}
I'm attempting to pull the data out to use during the ConfigureServices method, using the .Bind method:
public class DatabaseConnections
{
public string DatabaseUri { get; set; }
public string ApplicationKey { get; set; }
public string DatabaseName { get; set; }
}
private DatabaseConnections databaseSettings;
private DatabaseConnections DatabaseSettings
{
get
{
if (databaseSettings == null)
{
databaseSettings = new DatabaseConnections();
Configuration.Bind(databaseSettings);
}
return databaseSettings;
}
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IDocumentClient>(
new DocumentClient(
new Uri(DatabaseSettings.DatabaseUri),
DatabaseSettings.ApplicationKey));
}
However, when I perform the binding, the settings are all set to null. But if I try to do it without the model binding, it seems to work fine:
public void ConfigureServices(IServiceCollection services)
{
var databaseSettings = Configuration.GetSection("DatabaseConnections");
services.AddSingleton<IDocumentClient>(
new DocumentClient(
new Uri(databaseSettings.GetValue<string>("DatabaseUri")),
databaseSettings.GetValue<string>("ApplicationKey")));
}
What am I doing wrong?
You can either build a service provider or use string.
Configuration.GetSection("DatabaseConnections:DatabaseUri").Value
For example,
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<DatabaseConnections>(
Configuration.GetSection("DatabaseConnections"));
var sp = services.BuildServiceProvider();
var databaseConnections = sp.GetService<IOptions<DatabaseConnections>>();
services.AddSingleton<IDocumentClient>(
new DocumentClient(new Uri(databaseConnections.Value.DatabaseUri)),
databaseConnections.Value.ApplicationKey));
}
Controller
public class HomeController : Controller
{
private readonly DatabaseConnections _databaseConnections;
public HomeController(IOptions<DatabaseConnections> databaseConnections)
{
_databaseConnections = databaseConnections.Value;
}
}
The other answer is good if you want to use IOptions, for whatever reason I really don't like doing it and prefer binding to a class.
You can do this with a single line in your Configure Services method :
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(Configuration.GetSection("DatabaseConnections").Get<DatabaseConnections>());
}
It looks like you are missing the "Get" on the end which takes the configuration section and binds it to your class.
Further info : http://dotnetcoretutorials.com/2016/12/26/custom-configuration-sections-asp-net-core/
In one of my concrete class. I have the method.
public class Call : ICall
{
......
public Task<HttpResponseMessage> GetHttpResponseMessageFromDeviceAndDataService()
{
var client = new HttpClient();
var uri = new Uri("http://localhost:30151");
var response = GetAsyncHttpResponseMessage(client, uri);
return response;
}
Now I put the url into appsettings.json.
{
"AppSettings": {
"uri": "http://localhost:30151"
}
}
And I created a Startup.cs
public class Startup
{
public IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
}
}
and now I get stuck.
EDIT
By the way, I don't have a controller, it is a console application.
The preferred way to read configuration from appSettings.json is using dependency injection and the built or (or 3rd party) IoC container. All you need is to pass the configuration section to the Configure method.
public class AppSettings
{
public int NoRooms { get; set; }
public string Uri { get; set; }
}
services.Configure<AppSettings>(Configuration.GetSection("appsettings"));
This way you don't have to manually set the values or initialize the AppSettings class.
And use it in your service:
public class Call : ICall
{
private readonly AppSettings appSettings;
public Call(IOptions<AppSettings> appSettings)
{
this.appSettings = appSetings.Value;
}
public Task<HttpResponseMessage>GetHttpResponseMessageFromDeviceAndDataService()
{
var client = new HttpClient();
var uri = new Uri(appSettings.Uri);
var response = GetAsyncHttpResponseMessage(client, uri);
return response;
}
}
The IoC Container can also be used in a console application, you just got to bootstrap it yourself. The ServiceCollection class has no dependencies and can be instantiated normally and when you are done configuring, convert it to an IServiceProvider and resolve your main class with it and it would resolve all other dependencies.
public class Program
{
public static void Main(string[] args)
{
var configurationBuilder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json");
var configuration = configurationBuilder.Build()
.ReloadOnChanged("appsettings.json");
var services = new ServiceCollection();
services.Configure<AppSettings>(configuration.GetSection("appsettings"));
services.AddTransient<ICall, Call>();
// add other services
// after configuring, build the IoC container
IServiceProvider provider = services.BuildServiceProvider();
Program program = provider.GetService<Program>();
// run the application, in a console application we got to wait synchronously
program.Wait();
}
private readonly ICall callService;
// your programs main entry point
public Program(ICall callService)
{
this.callService = callService;
}
public async Task Run()
{
HttpResponseMessage result = await call.GetHttpResponseMessageFromDeviceAndDataService();
// do something with the result
}
}
Create a static class
public static class AppSettings
{
public static IConfiguration Configuration { get; set; }
public static T Get<T>(string key)
{
if (Configuration == null)
{
var builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
var configuration = builder.Build();
Configuration = configuration.GetSection("AppSettings");
}
return (T)Convert.ChangeType(Configuration[key], typeof(T));
}
}
then access the settings anywhere you want like
var uri = AppSettings.Get<string>("uri");
var rooms = AppSettings.Get<int>("noRooms");
appsettings.json example
{
"AppSettings": {
"uri": "http://localhost:30151",
"noRooms": 100
}
}
You can access data from the IConfigurationRoot as following:
Configuration["AppSettings:uri"]
Like suggested in the comment I would put the information in a seperate class for that info and pass it into the DI container.
the class
public class AppSettings {
public string Uri { get; set; }
}
DI
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(new AppSettings() { Uri = Configuration["AppSettings:uri"] });
// ...
}
Controller
public class DemoController
{
public HomeController(IOptions<AppSettings> settings)
{
//do something with it
}
}