ASP.NET Core appsettings.json在代码中更新

Sie*_*mko 16 c# json appsettings .net-core asp.net-core

我目前正在使用asp.net core v1.1开发项目,在我的appsettings.json中我有:

"AppSettings": {
   "AzureConnectionKey": "***",
   "AzureContainerName": "**",
   "NumberOfTicks": 621355968000000000,
   "NumberOfMiliseconds": 10000,
   "SelectedPvInstalationIds": [ 13, 137, 126, 121, 68, 29 ],
   "MaxPvPower": 160,
   "MaxWindPower": 5745.35
},
Run Code Online (Sandbox Code Playgroud)

我也有用来存储它们的类:

public class AppSettings
{
    public string AzureConnectionKey { get; set; }
    public string AzureContainerName { get; set; }
    public long NumberOfTicks { get; set; }
    public long NumberOfMiliseconds { get; set; }
    public int[] SelectedPvInstalationIds { get; set; }
    public decimal MaxPvPower { get; set; }
    public decimal MaxWindPower { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

并启用DI在Startup.cs中使用:

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
Run Code Online (Sandbox Code Playgroud)

有没有办法改变和保存MaxPvPowerMaxWindPower控制器?

我试过用

private readonly AppSettings _settings;

public HomeController(IOptions<AppSettings> settings)
{
    _settings = settings.Value;
}

[Authorize(Policy = "AdminPolicy")]
 public IActionResult UpdateSettings(decimal pv, decimal wind)
 {
    _settings.MaxPvPower = pv;
    _settings.MaxWindPower = wind;

    return Redirect("Settings");
 }
Run Code Online (Sandbox Code Playgroud)

但它没有做任何事情.

Ale*_*ock 14

我采用了 Qamar Zamans 代码(谢谢)并对其进行了修改,以允许编辑大于:一个:层:深的参数。

希望它可以帮助某人,惊讶地发现这不是某个地方的图书馆功能。

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

            SetValueRecursively(sectionPathKey, jsonObj, value);

            string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
            File.WriteAllText(filePath, output);

        }
        catch (Exception ex)
        {
            Console.WriteLine("Error writing app settings | {0}", ex.Message);
        }
    }

    private static void SetValueRecursively<T>(string sectionPathKey, dynamic jsonObj, T value)
    {
        // split the string at the first ':' character
        var remainingSections = sectionPathKey.Split(":", 2);

        var currentSection = remainingSections[0];
        if (remainingSections.Length > 1)
        {
            // continue with the procress, moving down the tree
            var nextSection = remainingSections[1];
            SetValueRecursively(nextSection, jsonObj[currentSection], value);
        }
        else
        {
            // we've got to the end of the tree, set the value
            jsonObj[currentSection] = value; 
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,Alex:我对此代码有一个改进建议:在递归调用之前添加以下行,以防止在节不存在的情况下出现 NullRef 异常。jsonObj[currentSection] ??= new JObject(); (2认同)

Qam*_*man 12

appsettings.json在运行时更新ASP.NET Core 中的文件。

拿这个示例appsettings.json文件:

{
  Config: {
     IsConfig: false
  }
}
Run Code Online (Sandbox Code Playgroud)

这是将IsConfig属性更新为 true的代码:

Main()
{
    AddOrUpdateAppSetting("Config:IsConfig", true);
}

public static void AddOrUpdateAppSetting<T>(string key, T value) 
{
    try 
    {
        var filePath = Path.Combine(AppContext.BaseDirectory, "appSettings.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");
    }
}
Run Code Online (Sandbox Code Playgroud)


Ank*_*kit 9

以下是Microsoft关于.Net Core Apps中的配置设置的相关文章:

Asp.Net核心配置

该页面还有示例代码,也可能有所帮助.

更新

我认为内存提供程序和绑定到POCO类可能有一些用处,但不能像预期的那样工作.

下一个选项可以是在添加配置文件并手动解析JSON配置文件并按预期进行更改时将AddJsonFile的reloadOnChange参数设置为true.

    public class Startup
    {
        ...
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }
        ...
    }
Run Code Online (Sandbox Code Playgroud)

... reloadOnChange仅在ASP.NET Core 1.1及更高版本中受支持.


Mat*_*ias 9

基本上你可以IConfiguration像这样设置值:

IConfiguration configuration = ...
// ...
configuration["key"] = "value";
Run Code Online (Sandbox Code Playgroud)

问题在于,例如,JsonConfigurationProvider没有实现将配置保存到文件中.正如您在源代码中看到的那样,它不会覆盖Set方法ConfigurationProvider.(见来源)

您可以创建自己的提供商并在那里实施保存.这里(实体框架自定义提供程序的基本示例)是如何执行此操作的示例.


Myk*_*ych 7

我看到大多数答案都使用Newtonsoft.Json包来更新设置。如果您需要更新一层深度的设置,您可以不使用Newtonsoft.Json并使用System.Text.Json(内置于 .Net Core 3.0 及更高版本)功能。这是一个简单的实现:

public void UpdateAppSetting(string key, string value)
{
    var configJson = File.ReadAllText("appsettings.json");
    var config = JsonSerializer.Deserialize<Dictionary<string, object>>(configJson);
    config[key] = value;
    var updatedConfigJson = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true });
    File.WriteAllText("appsettings.json", updatedConfigJson);
}
Run Code Online (Sandbox Code Playgroud)


Alp*_*glu 6

    public static void SetAppSettingValue(string key, string value, string appSettingsJsonFilePath = null)
    {
        if (appSettingsJsonFilePath == null)
        {
            appSettingsJsonFilePath = System.IO.Path.Combine(System.AppContext.BaseDirectory, "appsettings.json");
        }

        var json =   System.IO.File.ReadAllText(appSettingsJsonFilePath);
        dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JObject>(json);

        jsonObj[key] = value;

        string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);

        System.IO.File.WriteAllText(appSettingsJsonFilePath, output);
    }
Run Code Online (Sandbox Code Playgroud)


Mah*_*ani 6

根据 Qamar Zaman 和 Alex Horlock 的代码,我对它做了一些修改。

 public static class SettingsHelpers
 {
    public static void AddOrUpdateAppSetting<T>(T value, IWebHostEnvironment webHostEnvironment)
    {
        try
        {
            var settingFiles = new List<string> { "appsettings.json", $"appsettings.{webHostEnvironment.EnvironmentName}.json" };
            foreach (var item in settingFiles)
            {


                var filePath = Path.Combine(AppContext.BaseDirectory, item);
                string json = File.ReadAllText(filePath);
                dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);

                SetValueRecursively(jsonObj, value);

                string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
                File.WriteAllText(filePath, output);
            }
        }
        catch (Exception ex)
        {
            throw new Exception($"Error writing app settings | {ex.Message}", ex);
        }
    }



    private static void SetValueRecursively<T>(dynamic jsonObj, T value)
    {
        var properties = value.GetType().GetProperties();
        foreach (var property in properties)
        {
            var currentValue = property.GetValue(value);
            if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string) || property.PropertyType == typeof(decimal))
            {
                if (currentValue == null) continue;
                try
                {
                    jsonObj[property.Name].Value = currentValue;

                }
                catch (RuntimeBinderException)
                {
                    jsonObj[property.Name] = new JValue(currentValue);


                }
                continue;
            }
            try
            {
                if (jsonObj[property.Name] == null)
                {
                    jsonObj[property.Name] = new JObject();
                }

            }
            catch (RuntimeBinderException)
            {
                jsonObj[property.Name] = new JObject(new JProperty(property.Name));

            }
            SetValueRecursively(jsonObj[property.Name], currentValue);
        }


    }
}
Run Code Online (Sandbox Code Playgroud)