gpt4 book ai didi

c# - 如何将值更新到 appsettings.json 中?

转载 作者:行者123 更新时间:2023-12-01 23:37:34 24 4
gpt4 key购买 nike

我正在使用 IOptions 模式,如所述 in the official documentation .

当我从 appsetting.json 读取值时,这工作正常,但如何更新值并将更改保存回 appsetting.json

就我而言,我有一些可以从用户界面编辑的字段(由应用程序中的管理员用户)。因此,我正在寻找通过选项访问器更新这些值的理想方法。

最佳答案

在撰写此答案时,Microsoft.Extensions.Options 似乎没有提供任何组件。具有将配置值写回 appsettings.json 功能的软件包.

在我的一个 ASP.NET Core 中我想让用户能够更改一些应用程序设置的项目 - 这些设置值应存储在 appsettings.json 中,更准确地说是可选的appsettings.custom.json文件,如果存在,则会添加到配置中。

像这样...

public Startup(IHostingEnvironment env)
{
IConfigurationBuilder builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile("appsettings.custom.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables();

this.Configuration = builder.Build();
}

我声明了IWritableOptions<T>扩展的接口(interface)IOptions<T> ;所以我可以替换 IOptions<T>通过IWritableOptions<T>每当我想读取和写入设置时。

public interface IWritableOptions<out T> : IOptions<T> where T : class, new()
{
void Update(Action<T> applyChanges);
}

此外,我想出了 IOptionsWriter ,这是一个供 IWritableOptions<T> 使用的组件更新配置部分。这是我对前面提到的接口(interface)的实现...

class OptionsWriter : IOptionsWriter
{
private readonly IHostingEnvironment environment;
private readonly IConfigurationRoot configuration;
private readonly string file;

public OptionsWriter(
IHostingEnvironment environment,
IConfigurationRoot configuration,
string file)
{
this.environment = environment;
this.configuration = configuration;
this.file = file;
}

public void UpdateOptions(Action<JObject> callback, bool reload = true)
{
IFileProvider fileProvider = this.environment.ContentRootFileProvider;
IFileInfo fi = fileProvider.GetFileInfo(this.file);
JObject config = fileProvider.ReadJsonFileAsObject(fi);
callback(config);
using (var stream = File.OpenWrite(fi.PhysicalPath))
{
stream.SetLength(0);
config.WriteTo(stream);
}

this.configuration.Reload();
}
}

由于作者不了解文件结构,我决定将部分处理为 JObject对象。访问器尝试查找请求的部分并将其反序列化为 T 的实例,使用当前值(如果未找到),或者仅创建 T 的新实例,如果当前值为 null 。然后,该持有者对象被传递给调用者,调用者将对其应用更改。更改后的对象将转换回 JToken将替换该部分的实例...

class WritableOptions<T> : IWritableOptions<T> where T : class, new()
{
private readonly string sectionName;
private readonly IOptionsWriter writer;
private readonly IOptionsMonitor<T> options;

public WritableOptions(
string sectionName,
IOptionsWriter writer,
IOptionsMonitor<T> options)
{
this.sectionName = sectionName;
this.writer = writer;
this.options = options;
}

public T Value => this.options.CurrentValue;

public void Update(Action<T> applyChanges)
{
this.writer.UpdateOptions(opt =>
{
JToken section;
T sectionObject = opt.TryGetValue(this.sectionName, out section) ?
JsonConvert.DeserializeObject<T>(section.ToString()) :
this.options.CurrentValue ?? new T();

applyChanges(sectionObject);

string json = JsonConvert.SerializeObject(sectionObject);
opt[this.sectionName] = JObject.Parse(json);
});
}
}

最后,我为IServicesCollection实现了一个扩展方法。允许我轻松配置可写选项访问器...

static class ServicesCollectionExtensions
{
public static void ConfigureWritable<T>(
this IServiceCollection services,
IConfigurationRoot configuration,
string sectionName,
string file) where T : class, new()
{
services.Configure<T>(configuration.GetSection(sectionName));

services.AddTransient<IWritableOptions<T>>(provider =>
{
var environment = provider.GetService<IHostingEnvironment>();
var options = provider.GetService<IOptionsMonitor<T>>();
IOptionsWriter writer = new OptionsWriter(environment, configuration, file);
return new WritableOptions<T>(sectionName, writer, options);
});
}
}

可用于ConfigureServices就像...

services.ConfigureWritable<CustomizableOptions>(this.Configuration, 
"MySection", "appsettings.custom.json");

在我的Controller类我可以要求 IWritableOptions<CustomizableOptions>例如,具有与 IOptions<T> 相同的特征,但也允许更改和存储配置值。

private IWritableOptions<CustomizableOptions> options;

...

this.options.Update((opt) => {
opt.SampleOption = "...";
});

关于c# - 如何将值更新到 appsettings.json 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40970944/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com