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.

.NET Runtime
.NET Runtime
.NET: Microsoft Technologies based on the .NET software framework.Runtime: An environment required to run apps that aren't compiled to machine language.
1,119 questions
0 comments No comments
{count} vote

Accepted answer
  1. Jerry Cai-MSFT 986 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