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