13

I have a shared .NET Standard library that was originally being referenced by a .NET 4.8 MVC 4 project. There is a lot of code in this shared library that uses the ConfigurationManager, like:

var sze = ConfigurationManager.AppSettings["MaxAttachmentSize"];

This value for MaxAttachmentSize (and others) was being stored in the web.config.

Now I have a .NET 6 project that I'm building, which will use this same shared project, and I need to find a way to make these configuration app settings work in the new .NET Core application. What's the best way to do this?

My questions I guess are:

  • Is there a way to get ConfigurationManager to read from the .NET Core's appsettings.json file like it reads from web.config in the ASP.NET MVC 4 project?
  • If not, is there another configuration reader that I can use instead that will do double duty being able to work for both projects like I need?

The big spanner in the works though is the fact that all calls to ConfigurationManger right now are static, so if the .NET Core option could be static as well that would be incredibly helpful. If not, it'll just be more work moving the ASP.NET MVC 4 project to make those settings dependency injection available.

5 Answers 5

11

now you can get it even more easy

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

string sze = Configuration.GetSection("AppSettings:MaxAttachmentSize").Value;

after adding to appsettings.json

  "AppSettings": {
    "MaxAttachmentSize": "size1",
    "MinAttachmentSize": "size2"
  }
Sign up to request clarification or add additional context in comments.

5 Comments

Which package are you using for your code above? System.Configuration.ConfigurationManager? if so then I get an error that Configuration.GetSection need an object reference to work. if you're talking about Microsoft.Extensions.Configuration, then that doesn't work either because it also needs an instantiation of IConfiguration
It depends where in your code you are trying to get appsettings.json data. This code will be working in startup or (program for net6). If you trying to get data in another place you will have to inject IConfiguration.
Yeah, that's the issue. ConfigurationManager from net framework is a static method, which is what my shared project is using. Ideally i would find another static way of getting the appsettings.json variables
@Phil The only static way I know is to create a global static variable. From inside of startup you can assign value or even the whole config content. the most common way is using dependency injection of config , or injecting of special service
This is more easy? I weep for software developers
5

Using ASP .NET6

Install NuGet package System.Configuration.ConfigurationManager

The name of my configuration file is App.Config

Content of App.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <appSettings>
        <add key="DBConnectionString" value="aa" />
        <add key="DBName" value="bb" />
        <add key="AuthKey" value="cc" />
    </appSettings>
</configuration>

File reading values, i.e. SettingsService.cs:

using namespc = System.Configuration;

namespace Ecommerce_server.Services.SetupOperation
{
    public interface ISettingsService
    {
        string MongoDBConnectionString { get => namespc.ConfigurationManager.AppSettings["DBConnectionString"]!; }

        string DataBaseName { get => namespc.ConfigurationManager.AppSettings["DBName"]!; }

        public string AuthKey { get => namespc.ConfigurationManager.AppSettings["AuthKey"]!; }

    }

    public class SettingsService : ISettingsService
    {
        public string MongoDBConnectionString { get => namespc.ConfigurationManager.AppSettings["DBConnectionString"]!; }

        public string DataBaseName { get => namespc.ConfigurationManager.AppSettings["DBName"]!; }

        public string AuthKey { get => namespc.ConfigurationManager.AppSettings["AuthKey"]!; }

    }
}

Note: We had to create a specialized namespace for ConfigurationManger to solve ambiguity.

2 Comments

How does this interact with the settings hierarchy in .NET 6, where values are overridden based on where they are defined in. For example, Environment variables would override values in appsettings.json. Would that also work here with App.config?
The configuration system prioritizes the appsettings.json file over the App.config file. The values in the appsettings.json file will take precedence, and any values defined in the App.config file will be ignored. Although you can use both you would not use the same setting in both, otherwise it will not work and it's code duplication. So you should not worry which overriedes which if you do not use the same setting in both.
5

Reply from Serge is the correct one. .Net 6 and above is suggested to use appsettings.json instead of App.Config and using Microsoft.Extensions.Configurations namespace, instead of System.Configuraiton.ConfigurationManager here Microsoft describes how to use it.

create a appsettings.json file on the root like below

 "AppSettings": {
    "MaxAttachmentSize": "size1",
    "MinAttachmentSize": "size2"
  }

Inside the App.xaml.cs get an instance of IConfiguration

using System.Windows;
using Microsoft.Extensions.Configuration;

namespace WebSiteRatings
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public static IConfiguration Config { get; private set; }

        public App()
        {
            Config = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json")
                .Build();
        }
    }
}

And you can access within the app as below

string size = App.Config.GetSection("AppSettings:MaxAttachmentSize").Value;

1 Comment

".Net 6 and above is suggested to use appsettings.json instead" yeah, except that they have refused to make appsettings.json writable... so no modifying configuration at runtime that way...
1

We ran into a similar predicament where we have existing shared libraries that leverage reading directly from ConfigurationManager.AppSettings. These shared libraries were updated to dual target net8 and net48 but were not yet upgraded away from ConfigurationManager.AppSettings. We got around the issue for now by just dynamically copying the settings to ConfigurationManager.AppSettings.

For the net8 projects, we created the json config file like:

AppSettings": {
   "MaxAttachmentSize": "size1"
}

We read the json file within Program.cs and immediate invoke a method like this:

    /// <summary>
    /// Load specific settings from this file into the old ConfigurationManager.AppSettings that are used throughout a lot of our old code.
    /// </summary>
    public void PopulateConfigurationManagerAppSettings()
    {
        System.Configuration.ConfigurationManager.AppSettings["MaxAttachmentSize"] = MaxAttachmentSize;
    }

You could get creative using reflection or generic dictionaries to dynamically copy the values back to the old ConfigurationManager.AppSettings. This is just a simple brute force example to show you the essence of what we did.

Comments

0

For those upgrading to .Net 6 from .Net 4-ish:

  1. Migrate your app.config to appsettings.json. Wrap your settings with AppSettings or Config or whatever makes sense. The named top level wrapper allows you to compartmentalize your configs if needed.

Existing app.config:

<configuration>
  <appSettings>
    <add key="SomeKey" value="someValue" />

becomes appsettings.json:

{
  "Config": 
  {
    "SomeKey": "someValue"
  }
}
  1. Create a Config.cs POCO at the root to represent your file layout
public class Config{
  public string ConfigRoot = "Config";
  public string SomeKey { get => _someKey; set => _someKey=value; }
  private string _someKey = String.Empty;    
}
  1. Load the Config from appsettings.json in your Program.cs

Note: This is only needed if you need the config properties during startup.

//inject appsettings.json values
builder.Services.AddOptions();
builder.Configuration.GetSection("Config");

var app = builder.Build();
  1. Load the config as part of your Controller. You will now have to pass/push the config object from the controller into worker classes now.
public class MyController : ControllerBase
{
    private Config _Config;
    private IConfiguration _configuration;

    public MyController( IConfiguration configuration)
    {
        _configuration = configuration;
        _Config = new Config();
        _configuration.GetSection(_Config.ConfigRoot).Bind(_Config);
    }
}
  1. Use the config value in your controller method

string myConfigKey = _Config.SomeKey;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.