Read And Modify appsettings.json File In .Net Core

In this article, we are going to learn how to modify in appsettings.json file in .NET Core.

To achieve this we need to apply some code in the controller, let’s understand with an example that we have Locations key in the appsetting.json file and we need to modify its value in the controller.

Create one project in Visual Studio 2019.

Once the project is created open HomeController and paste the below code in it.

using AppSettingDemo1.Models;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Diagnostics;
using WrittingAppSettingDemo.Models;
using WrittingAppSettingDemo.Services.Interface;

namespace AppSettingDemo1.Controllers
{
  public class HomeController : Controller
  {
    private readonly IWritableOptions<Locations> _writableLocations;
    public HomeController(IWritableOptions<Locations> writableLocations)
    {
      _writableLocations = writableLocations;
    }
    public IActionResult Index()
    {
      return View();
    }

    public IActionResult ChangeAppSettingValue(string value)
    {
      _writableLocations.ChangeAppSettingValue(opt =>
      {
        opt.Name = value;
      });
      return RedirectToAction("Index");
    }

    public IActionResult Privacy()
    {
      return View();
    }

    [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
    public IActionResult Error()
    {
      return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
    }
  }
}

Create Services folder and create IWritableOptions Interface in it and paste below code.

using Microsoft.Extensions.Options;
using System;

namespace WrittingAppSettingDemo.Services.Interface
{
  public interface IWritableOptions<out T> : IOptions<T> where T : class, new()
  {
    void ChangeAppSettingValue(Action<T> applyChanges);
  }
}

Create WritableOptions class in the same Services folder and paste the below code in it.

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using WrittingAppSettingDemo.Services.Interface;

namespace WrittingAppSettingDemo.Services
{
  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 ChangeAppSettingValue(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();
    }
  }
}

Create a Helper folder in it creates one ServiceCollectionExtensions class and paste the below code in it.

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using WrittingAppSettingDemo.Services;
using WrittingAppSettingDemo.Services.Interface;

namespace WrittingAppSettingDemo.Helper
{
  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);
      });
    }
  }
}

Create Locations class in a model folder and paste the below code in it.

namespace WrittingAppSettingDemo.Models
{
  public class Locations
  {
    public Locations()
    {
      Name = "default";
    }
    public string Name { get; set; }
  }
}

Open Startup.cs file and add below line in ConfigureServices.

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using WrittingAppSettingDemo.Helper;
using WrittingAppSettingDemo.Models;

namespace AppSettingDemo1
{
  public class Startup
  {
    public Startup(IConfiguration configuration)
    {
      Configuration = configuration;
    }
    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
      services.ConfigureWritable<Locations>(Configuration.GetSection("Locations"));
      services.AddControllersWithViews();
    }
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
      if (env.IsDevelopment())
      {
        app.UseDeveloperExceptionPage();
      }
      else
      {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
      }
      app.UseHttpsRedirection();
      app.UseStaticFiles();

      app.UseRouting();

      app.UseAuthorization();

      app.UseEndpoints(endpoints =>
      {
        endpoints.MapControllerRoute(
                  name: "default",
                  pattern: "{controller=Home}/{action=Index}/{id?}");
      });
    }
  }
}

Open Index view and add the following code to it.

@{
  ViewData["Title"] = "Home Page";
}
<div class="text-center">
  <h1 class="display-4">Welcome</h1>
  <form asp-action="ChangeAppSettingValue" method="post">
    <input name="value" type="text" />
    <input type="submit" value="submit" />
  </form>
</div>

My appsetting.json file contains the following code.

As you can see in the above image there are Locations that contain the Name key and its value is “shaikh” which we are going to change using the above code.

Output

Also check, Upload Large Excel In Angular With .Net API Using Stored Procedure

1 Comment

  1. Ram

    Hi Shaikh,
    Thanks for the article. As I’m new to .Net and I’m using VS 2022, I’m not sure how to map the 2019 project with 2022 as it runs to some errors.
    Any suggestions would be appreciated.

    cheers,
    Ram

    0
    0
    Reply

Submit a Comment

Your email address will not be published.

Subscribe

Select Categories