Как прочитать значения 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)
Это позволяет:
- ChainedConfigurationProvider: добавляет существующую IConfiguration в качестве источника. В случае конфигурации по умолчанию добавляет конфигурацию хоста и устанавливает ее в качестве первого источника для конфигурации приложения.
- appsettings.json с помощью поставщика конфигурации JSON.
- appsettings.Environment.json с помощью поставщика конфигурации JSON. Например, appsettings.Production.json и appsettings.Development.json.
- Секреты приложения при запуске приложения в среде разработки.
- Переменные среды, использующие поставщик конфигурации переменных среды.
- Аргументы командной строки с использованием поставщика конфигурации командной строки.
Это означает, что вы можете ввести 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
- Создайте файл.json в корневом каталоге
- В вашем коде:
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 -> щелкните Свойства -> выберите Копировать, если новее:
Наконец, вы можете:
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, а затем для чтения из настроек приложения вы можете использовать один из следующих методов:
Получить данные раздела
var redisConfig = configuration.GetSection("RedisConfig");
Получить значение в разделе
var redisServer = configuration.GetValue<string>("RedisConfig:ServerName");
Получить вложенное значение в разделе
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();