1

I have this appsetting json file :

"RavenOptions": {
    "PublicUrl": "http://127.0.0.1:61570",
    "PublicDbName": "TestHostBuilder_ctor_1",
    "TseDbName": "TestHostBuilder_ctor_1",
    "IsHttps": "false",
    "CertificateDirectory": "",
    "ShardUrls": [
      "http://127.0.0.1:61570",
      "http://127.0.0.1:61570",
      "http://127.0.0.1:61570",
      "http://127.0.0.1:61570"
    ]
  }

I need to update the values of the file in runtime .I am using this function :

 public static void AddOrUpdateAppSetting<T>(string key, T value)
    {
        try
        {
            var filePath = Path.Combine(AppContext.BaseDirectory, "appSettingTest.json");
            string json = File.ReadAllText(filePath);
            dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

            var sectionPath = key.Split(":")[0];

            if (!string.IsNullOrEmpty(sectionPath))
            {
                var keyPath = key.Split(":")[1];
                jsonObj[sectionPath][keyPath] = value;
            }
            else
            {
                jsonObj[sectionPath] = value; // if no sectionpath just set the value
            }

            string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
            File.WriteAllText(filePath, output);
        }
        catch (ConfigurationErrorsException)
        {
            Console.WriteLine("Error writing app settings");
        }
    }

this function works fine but the problem is when I want to update the values of sharedurls (this is an array) the result is like this :

enter image description here

All records are in one row .But I need tho be like this :

enter image description here

every records is one row. Here is my update code :

string serverAddress = "\""+documentStore.Identifier.Split("(").First()+"\"";
        Appset.AddOrUpdateAppSetting("RavenOptions:PublicDbName", documentStore.Database);
        Appset.AddOrUpdateAppSetting("RavenOptions:PublicUrl", documentStore.Identifier.Split("(").First());
        Appset.AddOrUpdateAppSetting("RavenOptions:ShardUrls","["+String.Join(",", Enumerable.Repeat(serverAddress, 4).ToArray())+"]");
Ehsan Akbar
  • 6,977
  • 19
  • 96
  • 180
  • First, why are you doing this instead of using a better config source like eg a database? `appsettings.json` is nothing special, it's just a default JSON file name. Second, ASP.NET Core uses System.Text.Json. Why add yet another dependency to JSON.NET ? Or go through `dynamic`? Both with JSON.NET and STJ you can parse the entire document, modify a node and save it back. With STJ you can use [Parse](https://learn.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument.parse?view=net-6.0). There's no reason to split names and values, that's done by the JSON serializer – Panagiotis Kanavos May 09 '22 at 07:39
  • As for `all records are in one row` it doesn't matter **at all** as long as the values are in an array. One row or many, when any JSON setting file (which doesn't have to be appsettings.json` is loaded, the array index value will be appended to the section/value path. – Panagiotis Kanavos May 09 '22 at 07:42
  • @PanagiotisKanavos thanks for your response ,In fact I am using ravenTestDriver for my unittests,RavenTestDriver is a fake inmemory databae for ravendb .when I run my test the diver sets a random port for the database,so I have to inject this port to my application using jsonfile .I hope that I could explain the problem – Ehsan Akbar May 09 '22 at 07:46
  • @PanagiotisKanavos here in my test I should inject Ioption to main application : services.Configure>(options => Configuration.GetSection("RavenOptions").Bind(options)); – Ehsan Akbar May 09 '22 at 07:48
  • @PanagiotisKanavos as you can see Configuration.GetSection("RavenOptions").Bind(options) returns the values from raventestdriver that I set before and inject it ti my application ,any solution I will be appreciated – Ehsan Akbar May 09 '22 at 07:51
  • This doesn't explain why you used such code at all. The problem isn't RavenDB. It looks like you [copied these answers](https://stackoverflow.com/questions/41653688/asp-net-core-appsettings-json-update-in-code) which don't work for arrays. You can't "emulate" a JSON array value, you must store an actual JSON array object. A `T[]` instead of a `T` and *definitely* not a string – Panagiotis Kanavos May 09 '22 at 07:51
  • To resume, you want edit a json file. Maybe this can help you : [Modifying JSON](https://www.newtonsoft.com/json/help/html/ModifyJson.htm) – vernou May 09 '22 at 08:08
  • @PanagiotisKanavos string[] shardurl=new string[] { serverAddress,serverAddress,serverAddress,serverAddress}; Appset.AddOrUpdateAppSetting("RavenOptions:ShardUrls", JsonConvert.SerializeObject(shardurl)); is it true? – Ehsan Akbar May 09 '22 at 08:14

0 Answers0