net Core 读取和修改json文件

定义一个IOptions<T>的扩展接口IWritableOptions<T>来进行读写设置

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

接口实现类WritableOptions<T>

复制代码
public interface IWritableOptions<out T> : IOptionsSnapshot<T> where T : class, new()
{
    void Update(Action<T> applyChanges);
}

public class WritableOptions<T> : IWritableOptions<T> where T : class, new()
{
    private readonly IHostingEnvironment _environment;
    private readonly IOptionsMonitor<T> _options;
    private readonly string _section;
    private readonly string _file;

    public WritableOptions(
        IHostingEnvironment environment,
        IOptionsMonitor<T> options,
        string section,
        string file)
    {
        _environment = environment;
        _options = options;
        _section = section;
        _file = file;
    }

    public T Value => _options.CurrentValue;
    public T Get(string name) => _options.Get(name);

    public void Update(Action<T> applyChanges)
    {
        var fileProvider = _environment.ContentRootFileProvider;
        var fileInfo = fileProvider.GetFileInfo(_file);
        var physicalPath = fileInfo.PhysicalPath;

        var jObject = JsonConvert.DeserializeObject<JObject>(File.ReadAllText(physicalPath));
        var sectionObject = jObject.TryGetValue(_section, out JToken section) ?
            JsonConvert.DeserializeObject<T>(section.ToString()) : (Value ?? new T());

        applyChanges(sectionObject);

        jObject[_section] = JObject.Parse(JsonConvert.SerializeObject(sectionObject));
        File.WriteAllText(physicalPath, JsonConvert.SerializeObject(jObject, Formatting.Indented));
    }
}
复制代码
IServiceCollection扩展方法
复制代码
public static class ServiceCollectionExtensions
{
    public static void ConfigureWritable<T>(
        this IServiceCollection services,
        IConfigurationSection section,
        string file = "appsettings.json") where T : class, new()
    {
        services.Configure<T>(section);
        services.AddTransient<IWritableOptions<T>>(provider =>
        {
            var environment = provider.GetService<IHostingEnvironment>();
            var options = provider.GetService<IOptionsMonitor<T>>();
            return new WritableOptions<T>(environment, options, section.Key, file);
        });
    }
}
复制代码

创建json文件(默认appsettings.json)

{
  "MySection": {
    "Name": "abc",
    "Age": 22
  }
}

 

在startup中绑定json文件节点MySection到MyClass

services.ConfigureWritable<MyClass>(Configuration.GetSection("MySection"));

也可以自定义要保存的json文件

services.ConfigureWritable<MyClass>(Configuration.GetSection("MySection"), "appsettings.custom.json");

当自定义保存到json文件的时候,要在项目启动时候添加自定义文件

复制代码
 public class Program
    {
        public static void Main(string[] args)
        {
            // BuildWebHost(args).Run();
            
            var host = BuildWebHost(args) 
             .Migrate();//初始化数据
            host.Run();
        }

        public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
               .ConfigureAppConfiguration(config => config.AddJsonFile("appsettings.custom.json", optional: true, reloadOnChange: true))
                .UseStartup<Startup>()
                .Build();
    }
复制代码

 

控制器中注入

复制代码
public class HomeController : BaseController
    {
          private readonly IWritableOptions<MyClass> _options;
          public HomeController(IWritableOptions<MyClass> options)
          {
               _options = options;
          }
           public IActionResult Index()
          {
            _options.Update(opt => {
                opt.Name = "value1";
                opt.Age =1;
            });
          }
    }                
复制代码

更新节点的Name为value1 ,Age为1

 
posted @   fy___~  阅读(822)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示