Saving To appsettings.json

James Tankersley 26 Reputation points
2021-03-04T23:15:24.647+00:00

I'd like to be able to use a form to enable users to edit a custom section of the appsettings.json file. I can't find any documentation on how to accomplish this, I'm currently building a web app using VS 2019 and .NET 5.

Developer technologies .NET .NET Runtime
0 comments No comments
{count} vote

Accepted answer
  1. Jerry Cai-MSFT 991 Reputation points
    2021-03-08T03:12:45.13+00:00

    Hi, JamesTankersley

    To edit appsettings.json in a form, you can check my demo:

    IWritableOptions:

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

    WritableOptions:

    public class WritableOptions<T> : IWritableOptions<T> where T : class, new()
        {
            private readonly IHostingEnvironment _environment;
            private readonly IOptionsMonitor<T> _options;
            private readonly IConfigurationRoot _configuration;
            private readonly string _section;
            private readonly string _file;
    
            public WritableOptions(
                IHostingEnvironment environment,
                IOptionsMonitor<T> options,
                IConfigurationRoot configuration,
                string section,
                string file)
            {
                _environment = environment;
                _options = options;
                _configuration = configuration;
                _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));
                _configuration.Reload();
            }
        }
    

    ServiceCollectionExtensions:

    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 configuration = (IConfigurationRoot)provider.GetService<IConfiguration>();
                    var environment = provider.GetService<IHostingEnvironment>();
                    var options = provider.GetService<IOptionsMonitor<T>>();
                    return new WritableOptions<T>(environment, options, configuration, section.Key, file);
                });
            }
        }
    

    Model:

    public class Locations
        {
            public Locations()
            {
                Name ="default";
            }
            public string Name { get; set; }
        }
    

    Controller:

    private readonly IWritableOptions<Locations> _writableLocations;
            public HomeController(IWritableOptions<Locations> writableLocations)
            {
                _writableLocations = writableLocations;
            }
    
            //Update Locations:Name
            public IActionResult Change(string value)
            {
                _writableLocations.Update(opt => {
                    opt.Name = value;
                });
                return RedirectToAction("Index");
            }
    

    View:

    <form asp-action="Change" method="post">
        <input name="value" type="text"/>
        <input type="submit"  value="submit"/>
    </form>
    

    And add this service to startup:

    services.ConfigureWritable<Locations>(Configuration.GetSection("Locations"));
    

    Result:

    eSTK7.gif
    Best Regards,
    Jerry Cai


    If the answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    4 people found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Chaker AICH 6 Reputation points
    2021-05-20T15:20:41.427+00:00

    Hi @Jerry Cai-MSFT
    Thank you for all explications.
    I would like how I can Relaod/Refrech services after the changing of AppSettings.json.
    Thanks


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.