Configuration.GetSection всегда возвращает ноль
Каждый раз звоню Configuration.GetSection
, Value
свойство возвращаемого объекта всегда равно нулю.
мой Startup
конструктор
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddEnvironmentVariables();
this.Configuration = builder.Build();
}
мой ConfigureServices
метод
public void ConfigureServices(IServiceCollection services)
{
services.Configure<SqliteSettings>(opts => Configuration.GetSection("SqliteSettings").Bind(opts));
services.AddOptions();
services.AddMvc();
}
мой appsettings.json
{
"SqliteSettings": {
"DataSource": "C:\\db.sqlite",
"NewDatabase": true,
"Version": 3
}
}
Класс, который я использую для определения SqliteSettings
public class SqliteSettings
{
public string DataSource { get; set; }
public bool? NewDatabase { get; set; }
public int? Version { get; set; }
public string Password { get; set; }
public long? CacheSize { get; set; }
// More properties
}
Я подумал, что JSON может потребоваться иметь одинаковое количество свойств для сопоставления, или это может быть связано с определениями типов данных, но, возможно, они совершенно не связаны.
16 ответов
Просто измените свой ConfigureServices
способ быть похожим на следующий
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<SqliteSettings>(Configuration.GetSection("SqliteSettings"));
services.AddMvc();
}
И это должно работать.
Согласно Документам Microsoft: "Когда GetSection возвращает соответствующий раздел, значение не заполняется. Ключ и путь возвращаются, когда раздел существует".
Если вы хотите увидеть значения этого раздела, вам нужно вызвать метод GetChildren(): Configuration.GetSection("SqliteSettings").GetChildren();
Или вы можете использовать:Configuration.GetSection("SqliteSettings").Get<SqliteSettings>()
, JSON не обязательно должен иметь одинаковое количество свойств для сопоставления. Для несопоставленных свойств, допускающих значение NULL, будет установлено значение NULL, а для свойств, не имеющих значения NULL, будут установлены значения по умолчанию (например, для int будет установлено значение 0)
- Щелкните правой кнопкой мыши на
appsettings.json
и перейдите в Свойства. - Выберите Копировать в выходной каталог = Копировать всегда.
Если все остальные ответы не устраняют проблему, другой причиной может быть то, что свойства класса Options являются частными (или не имеют доступных сеттеров).
Моя проблема заключалась в том, что экземпляр объекта метода .bind() не был инициализирован.
services.Configure<SqliteSettings>(opts => Configuration.GetSection("SqliteSettings").Bind(opts));
Итак, перед вызовом .bind(opts); Я инициализировал значение:
SqlliteSettings opts = new SqliteSettings();
Привязал переменную локальных настроек:
Configuration.GetSection(AppSettingsSectionName).Bind(opts);
И сделал регистрацию контейнера отдельно:
services.Configure<AppSettings>(Configuration.GetSection("SqlliteSettings"));
Это решило проблему, поскольку метод .Bind () просто вернет значение null, если предоставленный экземпляр имеет значение null.
Это работало для меня в консольном приложении
var conncetionString = config["ConnectionStrings:DefaultConnection"]
Убедитесь, что у вашего объекта конфигурации есть средства доступа к свойствам, иначе он не будет правильно привязан. Знание этого сэкономило бы мне 2 часа сегодня.
public class MyConfiguration
{
public string ConfigurationOption1; // BAD
public string ConfigurationOption2 { get; set; } // GOOD
}
В моем случае я использовал VS Code и .net core 3.x webapp.
Я столкнулся с аналогичной проблемой: GetSection() или Configuraton["Section:KeyName"] возвращал значение null, я проверил GetSection(). Exists (), который также вернул false.
Итак, я попытался добавить configbuilder внутри ConfigureServices, который помог мне это исправить,
public void ConfigureServices(IServiceCollection services)
{
//Initialize the builder
var builder = new ConfigurationBuilder()
.SetBasePath(Environment.CurrentDirectory)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")}.json", optional: true)//To specify environment
.AddEnvironmentVariables();//You can add if you need to read environment variables.
//Build the configuration
IConfiguration Configuration = builder.Build();
services.Configure<SqliteSettings>(Configuration.GetSection("SqliteSettings"));
//Similar to below
//services.Configure<EntityClass>(Configuration.GetSection("EntityConfigSection"));
}
Примечание. Убедитесь, что значение cwd и program в .VScode / launch.json имеет правильные значения. Код выбирает текущий рабочий каталог из значения cwd, поэтому нам нужно убедиться, что он установлен правильно.
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "X.X.X",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/<ProjectLocation>/bin/<BuildType>/<Version>/<ProjectDll>",
"args": [],
"cwd": "${workspaceFolder}/<ProjectLocation>",
"stopAtEntry": false,
"serverReadyAction": {
"action": "openExternally",
"pattern": "\\bNow listening on:\\s+(https?://\\S+)"
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
}
]}
var serviceProvider = services.BuildServiceProvider();
Должны прийти после всех услуг. Настроить звонки.
Если ваша инъекция зависимости не работает, и вы пришли к выводу, что этот метод является проблемой после его отладки, это не так!
Для регистрации достаточно:
services.Configure<SqliteSettings>(Configuration.GetSection("SqliteSettings"));
Вы должны ввести свой класс конфигурации в интерфейс IOptions . Это решит проблему DI. Я потратил несколько часов на эту проблему, надеюсь, это поможет кому-то другому.
Убедитесь, что вы случайно не вложили свои переменные в значения по умолчанию.
Logging
объект. Я вставлял всевозможные переменные в скобки неправильного уровня (но это было случайно правильно в appsettings.json по умолчанию), что приводило к загадочным отсутствием ключей / значений.
В моем случае для Web Api Core 2.1 я нуждался в этом в корневой папке проекта. Та же папка, что и Startup.cs, Program.cs.
Попробуйте добавить ConfigurationProvider в ConfigurationBuilder.
Конфигурация приложения предоставляется из:
- appsettings.json с помощью провайдера конфигурации файлов.
- appsettings. {Environment}.json с использованием поставщика конфигурации файлов.
Убедитесь, что вы добавили код в правильный файл appsettings.json. Может быть несколько файлов appsettings.json, таких как appsettings.Development.json, appsettings.QA.json, в зависимости от проекта и, следовательно, в зависимости от среды, ваш код будет выполнен.
Если у вас есть файл appsettings.Development.json, убедитесь, что настройки "ConnectionStrings:DefaultConnection" находятся в файлах appsettings.Development.json и appsettings.json.
У меня была эта проблема раньше, но моя проблема заключалась в том, что я поставил свой json
файл конфигурации в неправильном месте... я должен был положить его в wwwroot
папка потому что ядро asp.net ищет файлы в этой папке