Today, I was rewriting an old ASP.NET MVC5 Demo project to ASP.NET Core, and found that the way we used to read Web.config by ConfigurationManager.AppSettings[]
is no longer working. .NET Core has many new ways to achieve this. I picked one that suitable for my project. Here is how I do it.
The Classic ASP.NET Code
web.config
<appSettings>
<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=YOURACCOUNT;AccountKey=YOURKEY" />
<add key="AzureStorageAccountContainer" value="YOURCONTAINER" />
</appSettings>
Controller
private static CloudBlobContainer GetBlobContainer()
{
string connectionString = WebConfigurationManager.AppSettings["StorageConnectionString"];
blobClient.GetContainerReference(WebConfigurationManager.AppSettings["AzureStorageAccountContainer"]);
return container;
}
This is how we used to read web.config in ASP.NET. If you want to know more, please refer to my post《如何高逼格读取Web.config中的AppSettings》, which shows how to use a strong type configuration item. Now, in ASP.NET Core, we can do the same.
ASP.NET Core Settings Model
First, ASP.NET Core settings file is called appsettings.json, instead of web.config. In an ASP.NET Core application, web.config is only used by IIS when deployed to a Windows Server. It has nothing to do with ASP.NET Core itself.
The definition of appsettings.json is like:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
To add our own configuration:
{
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
},
"AppSettings": {
"StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=YOURACCOUNTNAME;AccountKey=YOURKEY",
"AzureStorageAccountContainer": "YOURCONTAINERNAME"
}
}
Next, create a new C# Class, and add the properties that match your configuration file:
public class AppSettings
{
public string StorageConnectionString { get; set; }
public string AzureStorageAccountContainer { get; set; }
}
Open Startup.cs, add the code for Configure AppSettings.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}
What this line of code does is whenever you use the type AppSettings in your code, it will return an instance of Configuration.GetSection("AppSettings")
. .NET Core will do the type converting and mapping, which is the same as I did in my 《如何高逼格读取Web.config中的AppSettings》
Finally, in your Controller, modify the constructor like this:
private AppSettings AppSettings { get; set; }
public HomeController(IOptions<AppSettings> settings)
{
AppSettings = settings.Value;
}
Then, we can use the strong type configuration values like this:
private CloudBlobContainer GetBlobContainer()
{
string connectionString = AppSettings.StorageConnectionString;
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container =
blobClient.GetContainerReference(AppSettings.AzureStorageAccountContainer);
return container;
}
If you like to use the AppSettings on Razor Views (.cshtml), you can DI into the view itself:
@using Microsoft.Extensions.Options;
@inject IOptions<AppSettings> Settings
And use it like this:
@Settings.Value.Copyright
For more advanced scenarios, refer to Microsoft docs here.
Abhilash
This helped a lot! Thanks!
Nick
Actually web.config has had a dedicated section for a while - why aren't you using that rather than generic appSettings?
Stephen
That was super helpful. Great job!
Christos
it works!! thanks
George
Thank you! I love this technique. One side effect, I noticed is that changes to your appsettings.*.json files won't take immediate affect. The application has to be stopped and restarted (IIS/IIS Express stopped and started in a web project) for the AppSettings DI object to be reloaded.
This is desirable in production but may be confusing while developing.
MrNams
Very helpful, what I liked is you put how it was working for .net framework and how it work for .net core . Thanks alot. One more question Is it safe to store password in connection string in appsettings.jason file??
Melvin
What if you want to read AppSettings from a method inside a custom class/model?
I have a generic http request handler and i want to read base URI from the AppSettings. I would like to the class to be able to pull the value directly. I don't want to feed it the settings/value every time I instantiate the class.
Subha Deb
Thanks, It's working for me too
Mike Pelton
Well I'd never have figured this out without you! Many thanks!
Hemant Jain
Very useful. Crisp and clear. Thanks
IdahoTaterHead
Thank you! There are several ways to skin a cat, but your pattern above keeps it straight forward, simple, and working great! I do, however, also add sections that are specific to controllers - Example) For a FileController, use a "FileManagementSettings" section in the appsettings.json together with a FileManagementSettings class (root folders, max file sizes etc) rather than a whole AppSettings section that contains more than is needed in the aforementioned controller. That's just my preference and I think it aligns well with the JSON structure in appsettings.json file and keeps the code readable etc.
Loran
That's the cat's meow - thanks.
Johan
Nice tutorial !! Save me a ton of pain. Thank you.