How to get json values and pass it in same appsetting json in .Netcore

Jaffer Sadiq Hussain 1 Reputation point
2021-11-02T12:52:46.16+00:00

Hi,

I have one requirement to pass the connection string as alias in same appsetting.json file. Is that achievable?

I would appreciate if someone support on this

"TestConnectionstring":"(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=xxxxxx)(PORT=xxxx))(CONNECT_DATA=(SERVICE_NAME=xxxxx)))",

"ConnectionString":"Data Source=TestConnectionstring; USERID=xxxxxx;PASSWORD=xxxxxx;",

Entity Framework Core
Entity Framework Core
A lightweight, extensible, open-source, and cross-platform version of the Entity Framework data access technology.
697 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,165 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Zhi Lv - MSFT 32,011 Reputation points Microsoft Vendor
    2021-11-03T01:56:57.207+00:00

    Hi @Jaffer Sadiq Hussain ,

    To get the json values from the appsetting.json file, you could use the Configuration.

    For example:

    Consider the following appsettings.json file:

    {  
      "Position": {  
        "Title": "Editor",  
        "Name": "Joe Smith"  
      },  
      "MyKey":  "My appsettings.json Value",  
      "Logging": {  
        "LogLevel": {  
          "Default": "Information",  
          "Microsoft": "Warning",  
          "Microsoft.Hosting.Lifetime": "Information"  
        }  
      },  
      "AllowedHosts": "*"  
    }  
    

    Then, we can get the value using the following code:

    public class TestModel : PageModel  
    {  
        // requires using Microsoft.Extensions.Configuration;  
        private readonly IConfiguration Configuration;  
      
        public TestModel(IConfiguration configuration)  
        {  
            Configuration = configuration;  
        }  
      
        public ContentResult OnGet()  
        {  
            var myKeyValue = Configuration["MyKey"];  
            var title = Configuration["Position:Title"];  
            var name = Configuration["Position:Name"];  
            var defaultLogLevel = Configuration["Logging:LogLevel:Default"];  
      
      
            return Content($"MyKey value: {myKeyValue} \n" +  
                           $"Title: {title} \n" +  
                           $"Name: {name} \n" +  
                           $"Default Log Level: {defaultLogLevel}");  
        }  
    }  
    

    To update the appsetting.json file's json values, you can refer the following sample:

    [Note] In this sample, we are using Newtonsoft.Json, you could install it via Nuget.

    Create a IWritableOptions:

    //Required using Microsoft.AspNetCore.Hosting;  
    //Required using Microsoft.Extensions.Configuration;  
    //Required using Microsoft.Extensions.Options;  
    //Required using Newtonsoft.Json;  
    //Required using Newtonsoft.Json.Linq;  
    
    public interface IWritableOptions<out T> : IOptions<T> where T : class, new()  
    {  
        void Update(Action<T> applyChanges);  
    }  
    public class WritableOptions<T> : IWritableOptions<T> where T : class, new()  
    {  
        private readonly IWebHostEnvironment _environment;  
        private readonly IOptionsMonitor<T> _options;  
        private readonly IConfigurationRoot _configuration;  
        private readonly string _section;  
        private readonly string _file;  
    
        public WritableOptions(  
            IWebHostEnvironment 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();  
        }  
    }  
    

    Then, create a ServiceCollectionExtensions class:

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

    Register the service in the ConfigureServices method:

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

    The appsetting.json file content as below:

    {  
      "ConnectionStrings": {  
        "DefaultConnection": "XXX"  
      },  
      "Logging": {  
        "LogLevel": {  
          "Default": "Information",  
          "Microsoft": "Warning",  
          "Microsoft.Hosting.Lifetime": "Information"  
        }  
      },  
      "Locations": {  
        "Name": "default value"  
      },  
      "AllowedHosts": "*"  
    }  
    

    Assume the Locations's Name property need to update, then, we can create a Locations class as below: If you want to change the connection string, you can create a ConnectionStrings class.

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

    And create a UpdateAppsetting action to update the name.

    public class HomeController : Controller  
    {   
        private readonly IWritableOptions<Locations> _writableLocations;  
        public HomeController(IWritableOptions<Locations> writableLocations)  
        {   
            _writableLocations = writableLocations;  
        }  
        public IActionResult UpdateAppsetting()  
        {  
            _writableLocations.Update(opt => {  
                opt.Name = "Updated";  
            });  
    
            return RedirectToAction(nameof(Index));  
        }  
    

    Code in the Index view page, add a button to trigger the UpdateAppsetting action:

    <a class="btn btn-light" asp-area="" asp-controller="Home" asp-action="UpdateAppsetting">Update Location Name</a>  
    

    Then, the result as below: we can see the value has been changed to "updated".

    145404-2.gif


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    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.

    Best regards,
    Dillion

    2 people found this answer helpful.
    0 comments No comments