Как прочитать значения AppSettings из файла.json в ASP.NET Core

Я настроил свои данные AppSettings в appsettings/Config .json следующим образом:

{
  "AppSettings": {
        "token": "1234"
    }
}

Я искал в Интернете, как читать значения AppSettings из файла.json, но я не смог получить ничего полезного.

Я старался:

var configuration = new Configuration();
var appSettings = configuration.Get("AppSettings"); // null
var token = configuration.Get("token"); // null

Я знаю, с ASP.NET 4.0 вы можете сделать это:

System.Configuration.ConfigurationManager.AppSettings["token"];

Но как мне это сделать в ASP.NET Core?

30 ответов

Решение

Это было несколько поворотов. Я изменил этот ответ, чтобы быть в курсе ASP.NET Core 2.0 (по состоянию на 26/02/2018).

Это в основном взято из официальной документации:

Для работы с настройками в приложении ASP.NET рекомендуется создавать только Configuration в вашем приложении Startup учебный класс. Затем используйте шаблон параметров для доступа к отдельным настройкам. Допустим, у нас есть appsettings.json файл, который выглядит так:

{
  "MyConfig": {
   "ApplicationName": "MyApp",
   "Version": "1.0.0"
   }

}

И у нас есть объект POCO, представляющий конфигурацию:

public class MyConfig
{
    public string ApplicationName { get; set; }
    public int Version { get; set; }
}

Теперь мы строим конфигурацию в Startup.cs:

public class Startup 
{
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        Configuration = builder.Build();
    }
}

Обратите внимание, что appsettings.json будет зарегистрирован по умолчанию в.NET Core 2.0. Мы также можем зарегистрировать appsettings.{Environment}.json Конфиг-файл для каждой среды, если это необходимо.

Если мы хотим внедрить нашу конфигурацию в наши контроллеры, нам нужно зарегистрировать ее во время выполнения. Мы делаем это через Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    // Add functionality to inject IOptions<T>
    services.AddOptions();

    // Add our Config object so it can be injected
    services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
}

И мы вводим это так:

public class HomeController : Controller
{
    private readonly IOptions<MyConfig> config;

    public HomeController(IOptions<MyConfig> config)
    {
        this.config = config;
    }

    // GET: /<controller>/
    public IActionResult Index() => View(config.Value);
}

Полный Startup учебный класс:

public class Startup 
{
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        Configuration = builder.Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        // Add functionality to inject IOptions<T>
        services.AddOptions();

        // Add our Config object so it can be injected
        services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
    }
}

.NET Core 3.0

Возможно, это не лучший способ получить значение из appsettings.json, но он прост и работает в моем приложении!!

Файл appsettings.json

{
    "ConnectionStrings": {
        "DefaultConnection":****;"
    }

    "AppSettings": {
        "APP_Name": "MT_Service",
        "APP_Version":  "1.0.0"
    }
}

Контроллер:

Сверху:

using Microsoft.Extensions.Configuration;

В вашем коде:

var AppName = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build().GetSection("AppSettings")["APP_Name"];

Прежде всего: имя сборки и пространство имен Microsoft.Framework.ConfigurationModel было изменено на Microsoft.Framework.Configuration. Поэтому вы должны использовать: например,

"Microsoft.Framework.Configuration.Json": "1.0.0-beta7"

как зависимость в project.json, Используйте бета5 или 6, если у вас не установлено 7. Тогда вы можете сделать что-то подобное в Startup.cs,

public IConfiguration Configuration { get; set; }

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
     var configurationBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
        .AddJsonFile("config.json")
        .AddEnvironmentVariables();
     Configuration = configurationBuilder.Build();
}

Если вы затем хотите получить переменную из config.json, вы можете получить ее сразу, используя:

public void Configure(IApplicationBuilder app)
    {
        // Add .Value to get the token string
        var token = Configuration.GetSection("AppSettings:token");
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync("This is a token with key (" + token.Key + ") " + token.Value);
        });
    }

или вы можете создать класс с именем AppSettings следующим образом:

public class AppSettings
{
    public string token { get; set; }
}

и настройте сервисы так:

public void ConfigureServices(IServiceCollection services)
{       
    services.AddMvc();

    services.Configure<MvcOptions>(options =>
    {
        //mvc options
    });

    services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}

и затем получить к нему доступ, например, через контроллер, как это:

public class HomeController : Controller
{
    private string _token;

    public HomeController(IOptions<AppSettings> settings)
    {
        _token = settings.Options.token;
    }
}

В.NET Core 2.0 все немного изменилось. Конструктор запуска принимает объект конфигурации в качестве параметра, поэтому с помощью ConfigurationBuilder не требуется. Вот мой:

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

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)
{
    services.Configure<StorageOptions>(Configuration.GetSection("AzureStorageConfig"));
}

Мой POCO это StorageOptions объект, упомянутый вверху:

namespace Brazzers.Models
{
    public class StorageOptions
    {
        public String StorageConnectionString { get; set; }
        public String AccountName { get; set; }
        public String AccountKey { get; set; }
        public String DefaultEndpointsProtocol { get; set; }
        public String EndpointSuffix { get; set; }

        public StorageOptions() { }
    }
}

И конфигурация на самом деле подраздел моего appsettings.json файл с именем AzureStorageConfig:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;",
    "StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=brazzerswebapp;AccountKey=Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==;EndpointSuffix=core.windows.net"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },

  "AzureStorageConfig": {
    "AccountName": "brazzerswebapp",
    "AccountKey": "Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==",
    "DefaultEndpointsProtocol": "https",
    "EndpointSuffix": "core.windows.net",
    "StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=brazzerswebapp;AccountKey=Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==;EndpointSuffix=core.windows.net"
  }
}

Единственное, что я добавлю, это то, что, поскольку конструктор изменился, я не проверял, нужно ли что-то делать для загрузки appsettings.<environmentname>.json в отличие от appsettings.json,

С Core 2.2, и самым простым способом...

public IActionResult Index([FromServices] IConfiguration config) 
{
    var myValue = config.GetValue<string>("MyKey");
}

appsettings.json автоматически загружается и доступен через конструктор или действие, и есть GetSection метод на IConfiguration также. Не нужно переделывать Startup.cs или же Program.cs если все что вам нужно это appsettings.json,

Если вы просто хотите получить значение токена, используйте

Configuration["AppSettings:token"]

Поэтому я сомневаюсь, что это хорошая практика, но она работает локально, и я обновлю ее, если произойдет сбой при публикации / развертывании (в веб-службе IIS).

Шаг 1.) Добавьте эту сборку в начало вашего класса (в моем случае, класса контроллера):

using Microsoft.Extensions.Configuration;

Шаг 2.) Добавьте это или что-то вроде этого:

var config = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json").Build();

Шаг 3.) Вызвать значение вашего ключа, выполнив это (возвращает строку):

config["NameOfYourKey"]

Для ASP.NET Core 3.1 вы можете следовать этой документации:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

Когда вы создаете новый проект ASP.NET Core 3.1, у вас будет следующая строка конфигурации в Program.cs:

Host.CreateDefaultBuilder(args)

Это позволяет:

  1. ChainedConfigurationProvider: добавляет существующую IConfiguration в качестве источника. В случае конфигурации по умолчанию добавляет конфигурацию хоста и устанавливает ее в качестве первого источника для конфигурации приложения.
  2. appsettings.json с помощью поставщика конфигурации JSON.
  3. appsettings.Environment.json с помощью поставщика конфигурации JSON. Например, appsettings.Production.json и appsettings.Development.json.
  4. Секреты приложения при запуске приложения в среде разработки.
  5. Переменные среды, использующие поставщик конфигурации переменных среды.
  6. Аргументы командной строки с использованием поставщика конфигурации командной строки.

Это означает, что вы можете ввести IConfigurationи получать значения с помощью строкового ключа, даже вложенные значения. подобноIConfiguration ["Parent:Child"];

Пример:

appsettings.json

{
  "ApplicationInsights":
    {
        "Instrumentationkey":"putrealikeyhere"
    }
}

WeatherForecast.cs

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;
    private readonly IConfiguration _configuration;

    public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        var key = _configuration["ApplicationInsights:InstrumentationKey"];

        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

Это сработало для меня .Net Core 5

У меня есть файл appsettings.development.json. У меня выбрана среда «Разработка», поэтому в моем файле development.json есть настройки. Вы можете использовать appsettings.josn со средой по умолчанию.

с этой конфигурацией

создал класс со свойствами конфигурации

Зарегистрировал мои звонки в Startup

Теперь я могу получить доступ к своему контроллеру

Следующие работы для Консольных приложений;

1- установить следующее nuget пакеты (.csproj);

<ItemGroup>
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0-preview2-35157" />
    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0-preview2-35157" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0-preview2-35157" />
  </ItemGroup>

2- Создать appsettings.json на корневом уровне. Щелкните правой кнопкой мыши и выберите "Копировать в выходной каталог" как "Копировать, если новее".

3- Пример файла конфигурации:

{
  "AppConfig": {
    "FilePath": "C:\\temp\\logs\\output.txt"
  }
}

4- Program.cs

configurationSection.Key а также configurationSection.Value будет иметь свойства конфигурации.

static void Main(string[] args)
{
    try
    {

        IConfigurationBuilder builder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        IConfigurationRoot configuration = builder.Build();
        // configurationSection.Key => FilePath
        // configurationSection.Value => C:\\temp\\logs\\output.txt
        IConfigurationSection configurationSection = configuration.GetSection("AppConfig").GetSection("FilePath");  

    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
}

Вот полный пример использования ASP.NET Core!

articles.json

{
  "shownArticlesCount": 3,
  "articles": [
    {
      "title": "My Title 1",
      "thumbnailLink": "example.com/img1.png",
      "authorProfileLink": "example.com/@@alper",
      "authorName": "Alper Ebicoglu",
      "publishDate": "2018-04-17",
      "text": "...",
      "link": "..."
    },
    {
      "title": "My Title 2",
      "thumbnailLink": "example.com/img2.png",
      "authorProfileLink": "example.com/@@alper",
      "authorName": "Alper Ebicoglu",
      "publishDate": "2018-04-17",
      "text": "...",
      "link": "..."
    },
  ]
}

ArticleContainer.cs

public class ArticleContainer
{
    public int ShownArticlesCount { get; set; }

    public List<Article> Articles { get; set; }
}

public class Article
{
    public string Title { get; set; }

    public string ThumbnailLink { get; set; }

    public string AuthorName { get; set; }

    public string AuthorProfileLink { get; set; }

    public DateTime PublishDate { get; set; }

    public string Text { get; set; }

    public string Link { get; set; } 
}

Startup.cs

public class Startup
{
    public IConfigurationRoot ArticleConfiguration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        ArticleConfiguration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("articles.json")
            .Build();
    }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddOptions();

        services.Configure<ArticleContainer>(ArticleConfiguration);
    }
}

Index.cshtml.cs

public class IndexModel : PageModel
{
    public ArticleContainer ArticleContainer { get;set; }

    private readonly IOptions<ArticleContainer> _articleContainer;

    public IndexModel(IOptions<ArticleContainer> articleContainer)
    {
        _articleContainer = articleContainer;
    }

    public void OnGet()
    {
        ArticleContainer = _articleContainer.Value;
    }
}

Index.cshtml.cs

<h1>@Model.ArticleContainer.ShownArticlesCount</h1>

Супер поздно на вечеринку, но если кто-то узнает об этом.

Вы можете вызвать IConfiguration из Microsoft.Extensions.Configuration;

public static IConfiguration Configuration { get; }
public static string MyAwesomeString = Configuration.GetSection("appSettings")["MyAwesomeString"].ToString();

Для.NET Core 2.0 вы можете просто:

Объявите ваши пары ключ / значение в appsettings.json:

{
  "MyKey": "MyValue
}

Вставьте службу конфигурации в startup.cs и получите значение, используя службу

using Microsoft.Extensions.Configuration;

public class Startup
{
    public void Configure(IConfiguration configuration,
                          ... other injected services
                          )
    {
        app.Run(async (context) =>
        {
            string myValue = configuration["MyKey"];
            await context.Response.WriteAsync(myValue);
        });

Вы можете просто использовать...

      var configurations = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

var db3 = configurations["ConnectionStrings:BookStoresDB2"];

Просто дополнил Юваль Ицчаков ответ.

Вы можете загрузить конфигурацию без функции компоновщика, вы можете просто вставить ее.

public IConfiguration Configuration { get; set; }

public Startup(IConfiguration configuration)
{
   Configuration = configuration;
}
      private readonly ILogger<WeatherForecastController> _logger;

private IConfiguration _configuration;

public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
{
    _logger = logger;

    _configuration = configuration;
}

[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
    //You can use any of these

    var db = _configuration.GetSection("ConnectionStrings").GetSection("BookStoresDB2").Value;

    var db1 = _configuration["ConnectionStrings:BookStoresDB2"];

    var db2 = _configuration.GetValue<string>("ConnectionStrings:BookStoresDB2");
}

Для ASP.NET Core 6.0 вы можете просто:

appsetting.json

      {
  "AppSettings": {
        "token": "1234"
    }
}

TestModel.cs

      using Microsoft.Extensions.Configuration

public class TestModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myToken = Configuration["AppSettings:Token"];        
        return Content($"myToken value: {myToken}");
    }
}

.NET Core 2.1.0

  1. Создайте файл.json в корневом каталоге
  2. В вашем коде:
var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); 
var config = builder.Build();

3. Установите следующие зависимости:

Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.json

4. Затем ВАЖНО: щелкните правой кнопкой мыши файл appsettings.json -> щелкните Свойства -> выберите Копировать, если новее:

  1. Наконец, вы можете:

    config ["ключ1"]

Учитывая, что мой файл конфигурации будет выглядеть так:

{
    "ConnectionStrings": "myconnection string here",
    "key1": "value here"
}

В дополнение к существующим ответам я хотел бы отметить, что иногда может быть полезно иметь методы расширения для IConfiguration для простоты.

Я сохраняю конфигурацию JWT в appsettings.json, поэтому мой класс методов расширения выглядит следующим образом:

public static class ConfigurationExtensions
{
    public static string GetIssuerSigningKey(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:SecurityKey");
        return result;
    }

    public static string GetValidIssuer(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:Issuer");
        return result;
    }

    public static string GetValidAudience(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:Audience");
        return result;
    }

    public static string GetDefaultPolicy(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Policies:Default");
        return result;
    }

    public static SymmetricSecurityKey GetSymmetricSecurityKey(this IConfiguration configuration)
    {
        var issuerSigningKey = configuration.GetIssuerSigningKey();
        var data = Encoding.UTF8.GetBytes(issuerSigningKey);
        var result = new SymmetricSecurityKey(data);
        return result;
    }

    public static string[] GetCorsOrigins(this IConfiguration configuration)
    {
        string[] result =
            configuration.GetValue<string>("App:CorsOrigins")
            .Split(",", StringSplitOptions.RemoveEmptyEntries)
            .ToArray();

        return result;
    }
}

Это экономит много строк, и вы просто пишете чистый и минимальный код:

...
x.TokenValidationParameters = new TokenValidationParameters()
{
    ValidateIssuerSigningKey = true,
    ValidateLifetime = true,
    IssuerSigningKey = _configuration.GetSymmetricSecurityKey(),
    ValidAudience = _configuration.GetValidAudience(),
    ValidIssuer = _configuration.GetValidIssuer()
};

Также можно зарегистрироваться IConfiguration например, как синглтон и внедрить его, где вам нужно - я использую контейнер Autofac, вот как вы это делаете:

var appConfiguration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
builder.Register(c => appConfiguration).As<IConfigurationRoot>().SingleInstance();

Вы можете сделать то же самое с MS Dependency Injection:

services.AddSingleton<IConfigurationRoot>(appConfiguration);

Они просто продолжают что-то менять - только что обновив VS и взяв всю бомбу проекта, на пути к восстановлению, и новый способ выглядит следующим образом:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

    if (env.IsDevelopment())
    {
        // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
        builder.AddUserSecrets();
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

Я продолжал пропускать эту строку!

.SetBasePath(env.ContentRootPath)

Способ.NET Core 2.2

(Несомненно, в следующей версии.NET Microsoft изменит его на что-то совершенно другое.)

1. appSettings.json

Это может выглядеть примерно так. Здесь мы загрузим Setting1 и Setting2.

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Setting1": "abc",
  "Setting2": 123
}

2. AppSettings.cs

Класс POCO для хранения Setting1 и Setting2. Мы загрузим appsettings.json в этот объект класса. Структура класса POCO должна соответствовать файлу JSON, при желании свойства могут быть вложены в другие свойства / классы.

public class AppSettings
{
    public string Setting1 { get; set; }
    public int Setting2 { get; set; }
}

3 Startup.cs

Загрузите appSettings.json в свой объект AppSettings и начните его использовать:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        AppSettings settings = new AppSettings();

        Configuration = configuration;
        configuration.Bind(settings);

        // Now start using it
        string setting1 = settings.Setting1;
        int setting2 = settings.Setting2;
    }

Получить его внутри контроллера как объект через вызов Get<YourType>()

public IActionResult Index([FromServices] IConfiguration config) { BillModel model= config.GetSection("Yst.Requisites").Get<BillModel>(); return View(model); }

Сначала вы должны ввести IConfiguration, а затем для чтения из настроек приложения вы можете использовать один из следующих методов:

  1. Получить данные раздела

    var redisConfig = configuration.GetSection("RedisConfig");
    
  2. Получить значение в разделе

    var redisServer = configuration.GetValue<string>("RedisConfig:ServerName");
    
  3. Получить вложенное значение в разделе

    var redisExpireMInutes = configuration.GetValue<int>("RedisConfig:ServerName:ExpireMInutes");
    

С использованием.NET 7со всем вProgram.cs

      var token = builder.Configuration["AppSettings:token"]

Вы можете попробовать следующий код. Это работает для меня.

public class Settings
{
    private static IHttpContextAccessor _HttpContextAccessor;

    public Settings(IHttpContextAccessor httpContextAccessor)
    {
        _HttpContextAccessor = httpContextAccessor;
    }

    public static void Configure(IHttpContextAccessor httpContextAccessor)
    {
        _HttpContextAccessor = httpContextAccessor;
    }

    public static IConfigurationBuilder Getbuilder()
    {
        var builder = new ConfigurationBuilder()
          .SetBasePath(Directory.GetCurrentDirectory())
          .AddJsonFile("appsettings.json");
        return builder;
    }

    public static string GetAppSetting(string key)
    {
        //return Convert.ToString(ConfigurationManager.AppSettings[key]);
        var builder = Getbuilder();
        var GetAppStringData = builder.Build().GetValue<string>("AppSettings:" + key);
        return GetAppStringData;
    }

    public static string GetConnectionString(string key="DefaultName")
    {
        var builder = Getbuilder();
        var ConnectionString = builder.Build().GetValue<string>("ConnectionStrings:"+key);
        return ConnectionString;
    }
}

Здесь я создал один класс для получения строки подключения и настроек приложения.

В файле Startup.cs необходимо зарегистрировать класс, как показано ниже.

public class Startup
{

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
        Settings.Configure(httpContextAccessor);
    }
}

Это был "обман"? Я только что сделал мою Конфигурацию в классе Startup статической, и затем я могу получить к ней доступ из любого места:

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    public static IConfiguration Configuration { get; set; }

Чтобы получить данные настроек в .Net 6, я использую интерфейс IConfiguration с добавленной некоторой абстракцией, которая помогает мне протестировать его в моих проектах, что делает мой код более гибким.

Например, в файле appsettings.json есть URL-адрес API:

      "ApiBaseUri": "https://dev.api.com/"

Чтобы минимизировать затраты на изменение кода в связи с тем, что механизм работы с конфигами будет изменен в следующей версии .Net Core framework, я использую обертку дляIConfigurationинтерфейс.

      public interface IConfigurationWrapper
{
    string? GetSectionValue(string key);
}

public class ConfigurationWrapper : IConfigurationWrapper
{
    private readonly IConfiguration _config;

    public ConfigurationWrapper(IConfiguration config)
    {
        _config = config;
    }

    public string? GetSectionValue(string key)
    {
        return _config.GetSection(key).Value;
    }
}

И, наконец, есть специальный интерфейс для представления настроек в файле конфигурации:

      public interface IAppSettings
{
    Uri? GetApiBaseUri();
}

public class AppSettings : IAppSettings
{
    private const string ApiBaseUriSettingName = "ApiBaseUri";

    private readonly IConfigurationWrapper _config;

    public AppSettings(IConfigurationWrapper config)
    {
        _config = config;
    }

    public Uri? GetApiBaseUri()
    {
        string uriValue = _config.GetSectionValue(ApiBaseUriSettingName);

        return string.IsNullOrEmpty(uriValue) ? null : new Uri(uriValue);
    }
}

И вот как я использую это в своем коде:

      public class MyService : IMyService
{
    private readonly IAppSettings _settings;

    private readonly IRestRequestFactory _requestFactory;
    private readonly IRestResponseFactory _responseFactory;

    public MyService(IAppSettings settings, IRestRequestFactory requestFactory, IRestResponseFactory responseFactory)
    {
        _settings = settings;
        _requestFactory = requestFactory;
        _responseFactory = responseFactory;
    }

    public async Task<decimal?> GetSomeEndpointResponseAsync(FilterModel filter, CancellationToken token)
    {
        var request = _requestFactory.CreatePostRequest(ApiUrls.SomeEndpoint, filter);

        var response = await _responseFactory.GetRestResponseAsync<ResponseResultModel<decimal?>>(request, _settings.GetApiBaseUri(), token);

        return response.Data?.Data;
    }
}

И я также могу легко прикрытьAppSettingsс модульными тестами:

      [TestFixture]
public class AppSettingsTests
{
    private Mock<IConfigurationWrapper> _configurationMock;

    private IAppSettings _settings;

    [SetUp]
    public void SetUp()
    {
        _configurationMock = new Mock<IConfigurationWrapper>();

        _settings = new AppSettings(_configurationMock.Object);
    }

    [Test]
    public void GetApiBaseUri_ApiBaseUriIsEmptyString_ReturnsNull()
    {
        // Arrange
        string uri = string.Empty;

        _configurationMock.Setup(m => m.GetSectionValue(It.IsAny<string>())).Returns(uri);

        // Act
        Uri? result = _settings.GetApiBaseUri();

        // Assert
        Assert.IsNull(result);
    }

    [Test]
    public void GetApiBaseUri_ApiBaseUriIsNull_ReturnsNull()
    {
        // Arrange
        string uri = null;

        _configurationMock.Setup(m => m.GetSectionValue(It.IsAny<string>())).Returns(uri);

        // Act
        Uri? result = _settings.GetApiBaseUri();

        // Assert
        Assert.IsNull(result);
    }
}

Надеюсь это поможет.

В дополнение к ответу Али вы должны ввести объект IConfiguration в конструктор:

appsettings.js

      {
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "AppSettings": {
      "ServerUrl": "some url"
  }
  
}

Определить класс AppSettings

          public class AppSettings
    {
        public string ServerUrl { get; set; }
    }

Startup.cs

       public class Startup
    {
        private readonly IConfiguration Configuration;
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ...
        }
    }

Контроллер

          [Route("api/[controller]")]
    [ApiController]
    public class AuthenticationController : ControllerBase
    {
        private readonly AppSettings config;

        public AuthenticationController (IOptions<AppSettings> config)
        {
            this.config= config.Value;
        }

        [HttpGet("token")]

        public ActionResult Token()
        {
          var server=config.ServerUrl;

        }

Работает для .NET 5

С последней версией netcoreapp 3.1 вы можете делать это довольно просто, без каких-либо сторонних зависимостей.

Я создал для этого суть, но вы можете использовать этот класс для чтения файла JSON и возврата динамических свойств.

using System.Text.Json;
using System.IO;

class ConfigurationLoader
{

    private dynamic configJsonData;
    public ConfigurationLoader Load(string configFilePath = "appsettings.json")
    {
        var appSettings = File.ReadAllText(configFilePath);
        this.configJsonData = JsonSerializer.Deserialize(appSettings, typeof(object));
        return this;
    }

    public dynamic GetProperty(string key)
    {
        var properties = key.Split(".");
        dynamic property = this.configJsonData;
        foreach (var prop in properties)
        {
            property = property.GetProperty(prop);
        }

        return property;
    }
}

Я специально сделал это, чтобы использовать appconfig.json в моем консольном приложении dotnet. Я просто положил это в свойProgram.Main функция:

var config = new ConfigurationLoader();
config.Load();
Console.WriteLine(config.GetProperty("Environment.Name"));

И это вернет dynamicобъект в собственность. (JsonElement, если это не примитив). Мойappsettings.json файл выглядит так:

{
  "Environment": {
    "Token": "abc-123",
    "Name": "Production"
  }
}

Спасибо @ Брайан Мур

Изменяя конфигурацию на статическую в Startup.cs, я могу снова получить доступ к строке подключения с помощью одной строки кода:

Мой файл appsettings.json:

  "MyConnectionStrings": {
    "Connection1": "ConnectionString..."
  }
}

Мой файл Startup.CS, где я устанавливаю конфигурацию как статическую:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public static IConfiguration Configuration { get; set; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        services.AddDbContext<ITFixedAssetsContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ITFixedAssets")));
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseBrowserLink();
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseCookiePolicy();

        app.UseMvc();
    }
}

Доступ к значению моего соединения:

     string conString = Startup.Configuration.GetSection("MyConnectionStrings").GetSection("Connection1").Value.ToString();
Другие вопросы по тегам