appsettings in json file in new C# class library project [duplicate] - c#

This question already has an answer here:
Specify the application base path in ConfigurationBuilder in beta8
(1 answer)
Closed 7 years ago.
Well this shouldn't be this hard, I have a Class library package (new version from VS2015). Since I am referencing .Net 4.6 in the rest of the solution I removed the asp.Net5.4 completely from the project.json file for this library. I added the Configuration.Json package and the OptionsModel package as well, plus any dependencies. I am trying to follow some of the snippets I found on SO but none seem to get me anywhere.
MikesDotNetting has a good article on this but it only works in an mvc6 project OR a class library where you can reference MVC6 which doesnt work for me.
http://www.mikesdotnetting.com/article/284/asp-net-5-configuration
public class Startup
{
public IConfiguration Configuration { get; set; }
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
.AddJsonFile("config.json");
Configuration = builder.Build();
}
}
I see this in many of the examples, but ConfigurationBuilder takes an array of IConfigurationProviders, and appEnv.ApplicationBasePath is a string. So naturally this doesn't work here.
{
"Data": {
"DefaultConnection": {
"ConnectionString": "Server= (localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;"
},
"AppSetting": {
"SMSProvider": "betterSms",
"SMSAccountUser": "sakjfbhkdfbsdkfbksdfnbkdln",
"SMSAccountSecret": "dswkjgfhszdkfhdskfhdk",
"SMSPhoneFrom": "+15555555555"
}
}
}
I am simply trying to build a simple access mechanism to access the many appsettings contained in my config.json file.

You can access config variables in your app like:
var connString = Startup.Configuration.Get("Data:DefaultConnection:ConnectionString");

Related

.NET Core API call to a method in a .NET Project is saying it can't find Connection strings in the app.config file

I have a Core API project that was originally accessing the database from the controller (bad practice) so I moved the data access methods into an existing .NET class library where the connection strings are stored in the app.config file. The same connection strings are also located in the Core API project's appsettings.json/appsettings.development.json folders.
I then tried to access this new .NET class library method (containing the call to the database) from my API, but I'm getting the "can't find 'connectionstringname' in app.config" error. I'm new to .NET but a colleague was saying perhaps the app.config isn't getting pulled into the API's bin folder. Has anyone had problems with .NET Core projects struggling to communicate with .NET project's connection strings and how could I go about troubleshooting this?
1.) I tried pasting the app.config file into the API's bin folder, to no avail (same error.)
I've seen a few answers on SO but haven't been able to implement them successfully, so I apologize if this has been answered before.
You need to completely throw out your dot-net-framework understanding of config settings.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-5.0
Note the value of the url.
aspnet core fundamentals configuration
In DotNet-Core:
Highly recommend creating a first class object. (config-value-holder-poco)
And in your Ioc Registrations, inject the config-value-holder-poco into the Ioc (aka, "servicecollection" in dn-core).
And then constructor inject your settings poco holder.
As per the article.
Json "section"
"Position": {
"Title": "Editor",
"Name": "Joe Smith"
}
First class config-value-holder-poco.
public class PositionOptions
{
public const string Position = "Position";
public string Title { get; set; }
public string Name { get; set; }
}
IoC registration.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<PositionOptions>(Configuration.GetSection(
PositionOptions.Position));
}
Constructor Injection:
public class Test2Model : PageModel
{
private readonly PositionOptions _options;
public Test2Model(IOptions<PositionOptions> options)
{
_options = options.Value;
}
public ContentResult OnGet()
{
return Content($"Title: {_options.Title} \n" +
$"Name: {_options.Name}");
}
}
and now you can take advantage of the "refresh-rate" BUILT IN options for how these are treated.
https://medium.com/#kmar.ayush/eli5-ioptions-vs-ioptionssnaphot-vs-ioptionsmonitor-fab1d7e26a75
IOptions vs IOptionsSnaphot vs IOptionsMonitor

Console Application throwing a CS1069 Error when trying to use settings. C# .NET5 [duplicate]

I've got a method that reads settings from my config file like this:
var value = ConfigurationManager.AppSettings[key];
It compiles fine when targeting .NET Standard 2.0 only.
Now I need multiple targets, so I updated my project file with:
<TargetFrameworks>netcoreapp2.0;net461;netstandard2.0</TargetFrameworks>
But now, the compilation fails for netcoreapp2.0 with the following error message:
Error CS0103 The name 'ConfigurationManager' does not exist in the current context (netcoreapp2.0)
Separately, I created a new .NET Core 2.0 console application (only targeting .NET Core 2.0 this time), but likewise there seems to be no ConfigurationManager under the namespace System.Configuration.
I'm quite confused because it's available under .NET Standard 2.0, so I would expect it to be available in .NET Core 2.0, as .NET Core 2.0 is .NET Standard 2.0 compliant.
What am I missing?
Yes, ConfigurationManager.AppSettings is available in .NET Core 2.0 after referencing NuGet package System.Configuration.ConfigurationManager.
Credits goes to #JeroenMostert for giving me the solution.
I installed System.Configuration.ConfigurationManager from Nuget into my .net core 2.2 application.
I then reference using System.Configuration;
Next, I changed
WebConfigurationManager.AppSettings
to ..
ConfigurationManager.AppSettings
So far I believe this is correct. 4.5.0 is typical with .net core 2.2
I have not had any issues with this.
Once you have the packages setup, you'll need to create either an app.config or web.config and add something like the following:
<configuration>
<appSettings>
<add key="key" value="value"/>
</appSettings>
</configuration>
The latest set of guidance is as follows: (from https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#environment-variables)
Use:
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
From the docs:
public static class EnvironmentVariablesExample
{
[FunctionName("GetEnvironmentVariables")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
}
public static string GetEnvironmentVariable(string name)
{
return name + ": " +
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
}
}
App settings can be read from environment variables both when developing locally and when running in Azure. When developing locally, app settings come from the Values collection in the local.settings.json file. In both environments, local and Azure, GetEnvironmentVariable("<app setting name>") retrieves the value of the named app setting. For instance, when you're running locally, "My Site Name" would be returned if your local.settings.json file contains { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }.
The System.Configuration.ConfigurationManager.AppSettings property is an alternative API for getting app setting values, but we recommend that you use GetEnvironmentVariable as shown here.
I used below code example. Also this is so convenient way.
using Microsoft.Extensions.Configuration;
using System.IO;
namespace DemoWeppApp
{
public static class StaticConfigurationManager
{
public static IConfiguration AppSetting { get; }
static StaticConfigurationManager()
{
AppSetting = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
}
}
}
And then I can use easly in any static class like this
StaticConfigurationManager.AppSetting["conf_name"];
You can use Configuration to resolve this.
Ex (Startup.cs):
You can pass by DI to the controllers after this implementation.
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
Configuration = builder.Build();
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var microserviceName = Configuration["microserviceName"];
services.AddSingleton(Configuration);
...
}
I know it's a bit too late, but maybe someone is looking for easy way to access appsettings in .net core app.
in API constructor add the following:
public class TargetClassController : ControllerBase
{
private readonly IConfiguration _config;
public TargetClassController(IConfiguration config)
{
_config = config;
}
[HttpGet("{id:int}")]
public async Task<ActionResult<DTOResponse>> Get(int id)
{
var config = _config["YourKeySection:key"];
}
}

Is ConfigurationManager.AppSettings available in .NET Core 2.0?

I've got a method that reads settings from my config file like this:
var value = ConfigurationManager.AppSettings[key];
It compiles fine when targeting .NET Standard 2.0 only.
Now I need multiple targets, so I updated my project file with:
<TargetFrameworks>netcoreapp2.0;net461;netstandard2.0</TargetFrameworks>
But now, the compilation fails for netcoreapp2.0 with the following error message:
Error CS0103 The name 'ConfigurationManager' does not exist in the current context (netcoreapp2.0)
Separately, I created a new .NET Core 2.0 console application (only targeting .NET Core 2.0 this time), but likewise there seems to be no ConfigurationManager under the namespace System.Configuration.
I'm quite confused because it's available under .NET Standard 2.0, so I would expect it to be available in .NET Core 2.0, as .NET Core 2.0 is .NET Standard 2.0 compliant.
What am I missing?
Yes, ConfigurationManager.AppSettings is available in .NET Core 2.0 after referencing NuGet package System.Configuration.ConfigurationManager.
Credits goes to #JeroenMostert for giving me the solution.
I installed System.Configuration.ConfigurationManager from Nuget into my .net core 2.2 application.
I then reference using System.Configuration;
Next, I changed
WebConfigurationManager.AppSettings
to ..
ConfigurationManager.AppSettings
So far I believe this is correct. 4.5.0 is typical with .net core 2.2
I have not had any issues with this.
Once you have the packages setup, you'll need to create either an app.config or web.config and add something like the following:
<configuration>
<appSettings>
<add key="key" value="value"/>
</appSettings>
</configuration>
The latest set of guidance is as follows: (from https://learn.microsoft.com/en-us/azure/azure-functions/functions-dotnet-class-library#environment-variables)
Use:
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
From the docs:
public static class EnvironmentVariablesExample
{
[FunctionName("GetEnvironmentVariables")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
}
public static string GetEnvironmentVariable(string name)
{
return name + ": " +
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
}
}
App settings can be read from environment variables both when developing locally and when running in Azure. When developing locally, app settings come from the Values collection in the local.settings.json file. In both environments, local and Azure, GetEnvironmentVariable("<app setting name>") retrieves the value of the named app setting. For instance, when you're running locally, "My Site Name" would be returned if your local.settings.json file contains { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }.
The System.Configuration.ConfigurationManager.AppSettings property is an alternative API for getting app setting values, but we recommend that you use GetEnvironmentVariable as shown here.
I used below code example. Also this is so convenient way.
using Microsoft.Extensions.Configuration;
using System.IO;
namespace DemoWeppApp
{
public static class StaticConfigurationManager
{
public static IConfiguration AppSetting { get; }
static StaticConfigurationManager()
{
AppSetting = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
}
}
}
And then I can use easly in any static class like this
StaticConfigurationManager.AppSetting["conf_name"];
You can use Configuration to resolve this.
Ex (Startup.cs):
You can pass by DI to the controllers after this implementation.
public class Startup
{
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
Configuration = builder.Build();
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var microserviceName = Configuration["microserviceName"];
services.AddSingleton(Configuration);
...
}
I know it's a bit too late, but maybe someone is looking for easy way to access appsettings in .net core app.
in API constructor add the following:
public class TargetClassController : ControllerBase
{
private readonly IConfiguration _config;
public TargetClassController(IConfiguration config)
{
_config = config;
}
[HttpGet("{id:int}")]
public async Task<ActionResult<DTOResponse>> Get(int id)
{
var config = _config["YourKeySection:key"];
}
}

.NET Core Nancy application serving static files

I am trying to build a minimal viable web site as a .NET Core project using Nancy with some backend processing and static files as frontend which resides in default project folder wwwroot. The main problem is I don't understand how to make the app respond with static files, because default conventions don't apply to the new .NET Core project system.
Building Nancy applications as classic .NET Framework applications is well documented and there are many samples on the web on how to do it. But .NET Core projects (.xproj) differ a lot from classic .NET Framework projects (.csproj). I like the new project system a lot, but I don't understand how to integrate Nancy parts into it. And there is a lack of documentation and samples on how to do it.
TL;DR: GitHub repository, where the demo projects with all needed plumbing code resides. For Nancy v. 1.4.3 as well as for prerelease v. 2.0.0-barneyrubble.
Nancy v. 2, which supports .NET Core and .NET Standard is still in prerelease state, so even if you would like to stick with stable v. 1 branch - no problem.
Here's a step-by-step on how to do it from the scratch, which worked for me:
1) Create a new Empty ASP.NET Core Web Application
2) (Mandatory if you would like to stick with Nancy v. 1) Open project.json, remove "Microsoft.NETCore.App" dependency and change target framework from "netcoreapp1.0" to "net46", so frameworks section would look like that:
"frameworks": {
"net46": {}
},
3) Add the following dependencies to project.json: "Microsoft.AspNetCore.Owin" and "Nancy". At the time of writing the dependencies section of project.json for v. 1:
"dependencies": {
// Ommited dependencies
"Microsoft.AspNetCore.Owin": "1.0.0",
"Nancy": "1.4.3"
},
For v. 2:
"dependencies": {
// Ommited dependencies
"Microsoft.AspNetCore.Owin": "1.0.0",
"Nancy": "2.0.0-barneyrubble"
},
4) Create a class implementing IRootPathProvider and will provide a path to your wwwroot folder (WebRootPath property) at runtime by utilizing IHostingEnvironment object:
public class AppRootPathProvider : IRootPathProvider
{
private readonly IHostingEnvironment _environment;
public AppRootPathProvider(IHostingEnvironment environment)
{
_environment = environment;
}
public string GetRootPath()
{
return _environment.WebRootPath;
}
}
5) Create a class derived from DefaultNancyBootstrapper, which will retrieve IHostingEnvironment object and pass it to the previously defined Root Provider. It will also change default StaticContentsConventions with your own:
public class AppNancyBootstrapper : DefaultNancyBootstrapper
{
public AppNancyBootstrapper(IHostingEnvironment environment)
{
RootPathProvider = new AppRootPathProvider(environment);
}
protected override void ConfigureConventions(NancyConventions conventions)
{
base.ConfigureConventions(conventions);
conventions.StaticContentsConventions.AddDirectory("css");
conventions.StaticContentsConventions.AddDirectory("js");
conventions.StaticContentsConventions.AddDirectory("fonts");
}
protected override IRootPathProvider RootPathProvider { get; }
}
6) Open Startup class and replace the last line in Configure method with this one:
app.UseOwin(x => x.UseNancy(options => options.Bootstrapper = new AppNancyBootstrapper(env)));
It leverages Bootstrapper created in the previous step.
7) Now it's time to define your NancyModule. V. 1:
public class AppNancyModule : NancyModule
{
public AppNancyModule()
{
Get["/"] = _ => View["index"];
Get["/{fileName}"] = parameters => View[parameters.fileName];
}
}
V. 2:
public class AppNancyModule : NancyModule
{
public AppNancyModule()
{
Get("/", _ => View["index"]);
Get("/{fileName}", parameters => View[parameters.fileName]);
}
}
And you are good to go! Just place your static files in wwwroot - and fire off.

How can I use config.json to set environment-specific variables for a Visual Studio 2015/DNX project?

I have a Visual Studio 2015 solution made up of projects targeting DNX framework. I have been working locally but I plan to deploy to Azure environments (dev/test/prod). Naturally, the solution uses different database connection strings and other variables dependent on the environment. In the past I made use of cloud configuration files to set these variables, reading them with the CloudConfigurationManager.
I am given to understand that I need to use a config.json file. I have the following code in my Startup.cs file:
public Startup(IHostingEnvironment env, IApplicationEnvironment app)
{
Configuration = new ConfigurationBuilder(app.ApplicationBasePath)
.AddJsonFile("config.json")
.AddJsonFile($"config.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables()
.Build();
Configuration.Set("ASPNET_ENV", "Development");
}
My config.json file is currently an empty object { }. How do I add variables to this file (syntax?), and how do I access them from code?
Note this line in your startup code:
.AddJsonFile($"config.{env.EnvironmentName}.json", optional: true)
This adds an additional JSON config file which is named depending on your environment name. So add a new file to your project called:
config.<environment-name>.json
And set up the details in there, such as:
{
"AppSettings": {
"SomeVariable": "Blah"
},
"Data": {
"YourConnectionString": {
"ConnectionString": "<connection string here>"
}
}
}
For reading the configuration, there's a good answer here: Using IConfiguration globally in mvc6
You can use plain old JSON for that. For example, here's how to define a connection string:
{
"Foo": "Bar"
}
To access the configuration value, you do:
config.Get("username")
or:
config["username"];
You can find more information here: http://docs.asp.net/en/latest/fundamentals/configuration.html

Categories