configuration.getValue 或 configuration.getsection 总是返回 null
Posted
技术标签:
【中文标题】configuration.getValue 或 configuration.getsection 总是返回 null【英文标题】:configuration.getValue or configuration.getsection always returns null 【发布时间】:2019-05-27 00:58:31 【问题描述】:我是 .Net Core 的新手,并试图从 appsettings.json
文件中获取值,但我错过了一些非常基本的东西。请让我知道我做错了什么......
这是代码...
Program.cs
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
config.SetBasePath(Directory.GetCurrentDirectory());
)
Startup.cs
public IConfiguration Configuration get; private set;
public Startup(IConfiguration configuration)
Configuration = configuration;
public void ConfigureServices(IServiceCollection services)
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
Web API 控制器
private readonly IConfiguration config;
public EmailController(IConfiguration configuration)
if (configuration != null)
config = configuration;
动作方法
var emailTemplatesRelativePath = config.GetSection("EmailSettings");
var email = config.GetValue<string>("Email");
以上两行都为GetSection
和GetValue
返回空值
appsettings.json
"Logging":
"LogLevel":
"Default": "Trace",
"Microsoft": "Information"
,
"ConnectionStrings":
"FCRContext": "server=xxx;database=xxx;user id=xxx;password=xxx"
,
"AllowedHosts": "*",
"EmailSettings":
"EmailTemplatesPath": "EmailTemplates"
,
"Email": "aa@aa.com"
【问题讨论】:
你通常在Startup.cs
中初始化IConfiguration;不在Program.cs
。如果您按照您描述的方式获得 null,则说明那里有问题。请显示Startup.cs
docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/… 我正在关注这个。我也尝试了 Options Pattern,但是没有用...
.Net Core 2.2 并暂时使用 IIS Express..
【参考方案1】:
在 Controller 中访问配置与在 Startup.cs 中的工作方式略有不同。我之前做过这个,只需按照以下步骤操作:
Nuget:Microsoft.Extensions.Configuration.Binder
将您想要访问的所有配置放在控制器中的一个部分中,例如“电子邮件设置”:
appsettings.json
"EmailSettings":
"EmailTemplatesPath": "EmailTemplates",
"Email": "aa@aa.com"
然后在您的 Web API 项目中创建一个名为 EmailSettings.cs
的类:
EmailSettings.cs
public class EmailSettings
public string EmailTemplatesPath get; set;
public string Email get; set;
然后将您的配置值绑定到Startup.cs
中的EmailSettings
类的实例,并将该对象添加到依赖注入容器:
Startup.cs
public void ConfigureServices(IServiceCollection services)
...
EmailSettings emailSettings = new EmailSettings();
Configuration.GetSection("EmailSettings").Bind(emailSettings);
services.AddSingleton(emailSettings);
现在您可以在 Api 控制器中请求您的配置,只需将其添加到构造函数中,如下所示:
Web API 控制器
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
EmailSettings _emailSettings;
public ValuesController(EmailSettings emailSettings)
_emailSettings = emailSettings;
....
刚刚在我当前的项目(.NET Core 2.2 Web Api)中再次尝试,它成功了。我在 ValuesController 构造函数中放置了一个断点,_emailSettings 对象包含来自appsettings.json
文件的值。你应该可以复制和粘贴这个!玩得开心! :)
【讨论】:
不,这两行代码表明GetSection
和GetValue
都没有返回任何值。
更新为在控制器中工作。我自己测试过,试试看:)【参考方案2】:
在 IIS(或 IIS Express)内托管 in-process 时,Directory.GetCurrentDirectory()
将返回与运行 out-of-process 时返回的路径不同的路径。在 ASP.NET Core 2.1 之前,基于 IIS 的托管始终是进程外的,但 ASP.NET Core 2.2 引入了进程内运行的能力(这是创建新项目时的默认设置)。
在进程外运行时,Directory.GetCurrentDirectory()
将返回您的 ASP.NET Core 应用程序本身的路径,而在进程内运行时,它将返回到 IIS(或 IIS Express,例如“C: \Program Files\IIS Express")。
从你的问题来看,相关代码是这样的:
WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
config.SetBasePath(Directory.GetCurrentDirectory());
)
在这里,在您调用SetBasePath
之前,IConfigurationBuilder
已经设置为使用正确的路径。您的调用本身会覆盖此路径,将其设置为例如“C:\Program Files\IIS Express”。使用此 覆盖 基本路径,您的 appsettings.json
等文件将不再存在,因为它们不存在于例如“C:\Program Files\IIS Express”,因此不会从这些文件中加载配置。
解决方案只是删除您对ConfigureAppConfiguration
的调用,这样基本路径就不会被覆盖。我知道你已经发现了这一点,但我想确保你对这里出了什么问题有一个解释。
【讨论】:
在将其部署到 1) 旧版本的 IIS 或 2) 最新版本的 IIS 时是否有任何影响?如果我们为我们的项目设置了“进程中”,我们是否永远不会使用 config.SetBasePath,即使它在创建时就在项目中?如果是这样,我猜它只是 MS 没有更新它的模板。【参考方案3】:您犯了一个简单的错误,忘记在“EmailSettings”中添加“Email”。如下所示更新您的 json 并使用config.GetSection("EmailSettings")["Email"];
获取电子邮件
"EmailSettings":
"EmailTemplatesPath": "EmailTemplates",
"Email": "aa@aa.com"
,
希望这能解决您的问题。
编辑:
如果您想从 appsettings 中获取这些值,而不是启动,您应该将这些配置值加载到设置类中,然后将适当的 IOptions 实例注入您要在其中使用这些设置的方法构造函数。为此,请看我的回答here。
【讨论】:
这是两个独立的语句,表明它们都没有返回任何值。 您能否在此链接上看到我的答案,并通过设置类从 appsetting.json 获取这些值,然后使用 IOptions 将其注入控制器。 ***.com/a/53904527/5198054【参考方案4】:Program.cs
public class Program
public static void Main(string[] args)
CreateWebHostBuilder(args).Build().Run();
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
Startup.cs:
public partial class Startup
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.AddMvc();
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
app.UseMvcWithDefaultRoute();
控制器类
您需要使用 Bind() 方法从 section 中获取值。
EmailSetting option = new EmailSetting();
//You need to bind the section with data model,
//it will automatically map config key to property of model having same name
config.GetSection("EmailSettings").Bind(option);
//Alternative to this you can read nested key using below syntax
var emailTemplatesPath = config["EmailSettings:EmailTemplatesPath"];
var emailInEmailSettings = config["EmailSettings:Email"];
// If email key is not nested then you can access it as below
var email = config.GetValue<string>("EmailOutside");
电子邮件设置模型:-(属性名称应与配置键匹配)
public class EmailSetting
public string EmailTemplatesPath get; set;
public string Email get; set;
Appsetting.json:-
"AllowedHosts": "*",
"EmailSettings":
"EmailTemplatesPath": "EmailTemplates",
"Email": "aa@aa.com"
,
"EmailOutside": "aa@aa.com"
【讨论】:
这个config["EmailSettings:EmailTemplatesPath"]
仍然返回null
。
并据此docs.microsoft.com/en-us/dotnet/api/…绑定在.Net Core 2.2
中不可用
请尝试用一个控制器创建简单的MVC项目来读取配置文件。我已经更新了答案并在其中添加了代码示例。尽量保持这个虚拟项目非常简单,不要在管道中添加任何中间件,除了 MVC。
谢谢。这有帮助。我创建了一个空应用程序,它正确返回了配置值。然后我比较了这两个program.cs
,问题出在这一行我不得不 .ConfigureAppConfiguration((hostingContext, config.SetBasePath(Directory.GetCurrentDirectory()); )
不知道为什么会这样。 MSDN 说我需要添加... docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/…【参考方案5】:
虽然其他人已经解决了这个问题,但如果您想保持启动服务代码不变,只需将您的 Web API 控制器更改为以下内容:
private readonly EmailSettings _emailSettings;
public EmailController(IOptions<EmailSettings> emailSettings)
_emailSettings = emailSettings.Value;
重点是.Value。这就是您的代码返回 null 的原因。我还建议将 program.cs 更改回默认值。要在操作方法中使用它,只需执行以下操作:
_email.settings.EmailTemplatesPath
最后一件事 - 确保您的 EmailSettings 类结构与您的 json 完全相同。
【讨论】:
【参考方案6】:你可以这样做
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
services.AddTransient(p => p.GetRequiredService<IOptions<EmailSettings>>().Value);
并通过构造函数 DI 初始化 EmailSettings 对象。
【讨论】:
以上是关于configuration.getValue 或 configuration.getsection 总是返回 null的主要内容,如果未能解决你的问题,请参考以下文章
PHP MySql MsSql 如何插入或更新 ['] 或 ["] 或 [`] 字符?
jQuery 或原始 JavaScript 是不是预编译或缓存变量表达式或选择器?