如何在中绑定新选项对象.NET Core 3.1



我正在尝试使用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

最新更新