我正在尝试使用ASP在C#中编写一个扩展方法。NET Core 3.1和选项模式绑定提供程序中提供的任何现有配置(如appsettings.json(,或者如果找不到现有配置,则将默认对象绑定到配置。
我的目标是允许开发人员选择在appsettings.json中包含自己的自定义配置,或者只使用默认选项。
我遇到的问题是,当我尝试将对象SomeOptions
绑定到配置对象,然后稍后尝试通过调用Configuration.GetSection("SomeOptions").Get<SomeOptions>()
来检索IOptions<SomeOptions>
时,它总是返回一个null对象。
例如:
// Binding the creating options object to the configuration
var someOptions = new SomeOptions();
var section = Configuration.GetSection("SomeOptions")
section.Bind(someOptions);
// Retrieve the IOptions<SomeOptions> from the configuration
// This is the problem - it always returns null
var retrievedOptions = section.Get<SomeOptions>();
为什么新创建的对象没有绑定到配置
这是我写的函数:
/// <summary>
/// Adds options to the <see cref="IServiceCollection"/> injected services.
/// If no options can be found within configuration then the default options will be used.
/// </summary>
/// <param name="services">The <see cref="IServiceCollection"/> to add the option bindings to.</param>
/// <param name="configuration">The <see cref="IConfiguration"/> object used to retrieve the configuration sections from.</param>
/// <param name="sectionName">
/// The name of the configuration section to bind the options with.
/// If the configuration section cannot be found or it's blank the default configuration will be used instead.
/// </param>
/// <returns>The originally passed <see cref="IServiceCollection"/> with the added options.</returns>
public static IServiceCollection AddTransientOptionsWithDefault<TOptions>(this IServiceCollection services, IConfiguration configuration, string sectionName)
where TOptions : class, new()
{
if (configuration == null)
{
throw new ArgumentNullException(nameof(configuration));
}
// Retrieve any configured options
var section = configuration.GetSection(sectionName);
// If no configuration was found use the default options
var options = section.Get<TOptions>();
if (options == null)
{
options = new TOptions();
// This section here seems to be the issue.
// These are all of the different binding methods I've tried.
section.Bind(options);
//configuration.GetSection(sectionName).Bind(options);
//services.Configure<TOptions>(configureOptions => new TOptions());
//configuration.Bind(options);
}
// This returns null as it can't find the added TOptions
var newSection = configuration.GetSection(sectionName).Get<TOptions>();
// Another example - this returns an empty list
var sectionChildren = section.GetChildren();
services.Configure<TOptions>(section);
return services;
}
示例选项对象:
public class CorsOptions
{
public string[] Origins { get; set; } = Array.Empty<string>();
}
appsettings.json:
{
"Cors": {
"Origins": [ "www.google.com" ]
}
}
在现实世界中使用以上所有内容的示例。。。
Startup.cs片段:
private IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
AddCorsWithOrigins(services, Configuration);
}
private IServiceCollection AddCorsWithOrigins(IServiceCollection services, IConfiguration configuration)
{
// The idea here is that any "Cors" configuration will be used if it exists,
// otherwise it will just add the default IOptions<CorsOptions> instead
services.AddTransientOptionsWithDefault<CorsOptions>(configuration, "Cors");
// Retrieve the options that have been added to the configuration
var corsOptions = configuration.GetSection("Cors");
// Do something with the corsOptions object that has been added...
}
请确保导入软件包Microsoft。扩展。选项。ConfigurationExtensions。完成后,您可以将其绑定到自定义的Dto类。我试过以下内容:
serviceCollection。Configure(configuration.GetSection("Global"(;其中,AppSettingDto是我的自定义类,Global是我的appsettings json文件中的一个部分
public class AppSettingDto
{
public bool UseSendGrid { get; set; }
public string EmailFrom { get; set; }
}
"Global": {
"EmailFrom": "sunnylnct007@gmail.com",
"UseSendGrid": true
},
下面是帮助我解决问题的github链接https://github.com/dotnet/AspNetCore.Docs/issues/18833