覆盖 azure 应用服务应用程序设置中的数组

问题描述 投票:0回答:7

在我的 .NET Core 应用程序中,我向 appsettings.json 添加了一个数组,如下所示:

{
  "SettingsA": {
    "PropA": [
        "ChildObjectA": {
          ...
        },
        "ChildObjectB": {
          ...
        }
    ]
  }
}

如果我想在我的azure应用程序服务中的应用程序设置中覆盖该值,以便它将具有空数组:

{
  "SettingsA": {
    "PropA": []
  }
}

有办法做到这一点吗?

我试着放

SettingsA:PropsA  ->  []

在应用程序设置中,但它似乎没有覆盖appsettings.json的值

c# azure asp.net-core azure-web-app-service
7个回答
15
投票

为了补充这里已经给出的所有精彩答案,以下是我们在现实生活场景中的做法。

我们需要在应用程序设置中配置一组支持的语言。这是我们的 .NET Core 项目的 appSettings.json 中的样子:

{
    ...

    "SupportedLanguages": [
        {
            "Code": "en-AU",
            "Name": "English (Australia)"
        },
        {
            "Code": "en-GB",
            "Name": "English (United Kingdom)"
        },
        {
            "Code": "en-US",
            "Name": "English (United States)"
        }
    ]
}

这就是它最终在我们的 Azure 应用服务中的样子:

enter image description here

这有点繁琐,特别是如果您有更大或更复杂的层次结构,但我认为目前没有其他方法。


12
投票

这里的答案https://www.ryansouthgate.com/2016/03/23/iconfiguration-in-netcore/是你可以覆盖数组中的元素或添加其他元素,但他说你不能覆盖整个阵列,这看起来很奇怪。

覆盖语法使用从零开始的访问,例如 SettingsA:PropA:0:Something,我已在应用服务上尝试过此操作,并可以确认它是否有效。


3
投票

为此,在 Azure 上使用多平台语法,请使用 __

这种方式适用于 Windows 和 Linux 部署的应用服务:

SettingsA__PropA__0__Something

2
投票

您可以使用

AddEnvironmentVariables
属性来实现 覆盖 azure 上的应用程序设置 到本地设置。

首先在门户中配置设置: enter image description here

注意:这里的值为空。

要覆盖“应用程序设置”部分中的嵌套键,我们可以使用完整路径

SettingsA:PropA
作为名称或使用双下划线
SettingsA__PropA
来定义变量。你可以参考这篇文章

在本地,您可以进行如下配置: 在 Startup.cs 中:

public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            configuration = builder.Build();
        }
        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.AddMvc();
            services.AddOptions();
            services.Configure<SettingsOptions>(configuration.GetSection("SettingsA"));

        }

在 appsettings.json 中:

{"SettingsA": {
    "PropA": ["a","b"]
    }
}

在 HomeController 中:

private readonly IOptions<SettingsOptions> options;
        public HomeController(IOptions<SettingsOptions> options)
        {
            this.options = options;
        }

        public IActionResult Index()
        {
            var value = options.Value;
            ViewBag.Index = value.PropA+"success";
            return View();
        }

在设置选项中:

public class SettingsOptions
    {
        public string SettingsA { get; set; }
        public string PropA { get; set; }
    }

将项目发布到azure后,它将覆盖PropA值。 更多关于如何从asp.net core读取appsetting的详细信息,请关注这个案例


0
投票

这是微软团队非常奇怪的行为。看来他们并没有意识到现实是什么样的。

我最终得到了一个带有逗号分隔值的字符串而不是数组。


0
投票

(这个答案是对@Lukos'和@KenR's答案的补充。)

我遇到了与 OP 类似的场景,我需要在 Azure 门户中的 Web

App Service
的应用程序设置中覆盖值或清空数组。为了避免手动输入过程,我生成了 JavaScript,以自动将
appsettings.json
中使用的 JSON 转换为 Azure 门户中批量编辑/导入中使用的 JSON 格式。 此处此处列出了批量编辑/导入 JSON 格式。

enter image description here

enter image description here

下面的 HTML/CSS/JavaScript 代码段包含一个用于清空数组中所有值的复选框和一个用于设置分隔符的文本输入控件(例如

__
双下划线或
:
冒号)。

该代码片段很基本,在此作为简单示例列出。我上传了带有 UI 的完整工具来处理嵌套数组和属性。

document.addEventListener("DOMContentLoaded", initialize); let sourceEl, resultEl, separatorEl, emptyArrEl; let resultArr, sep, setValToEmpty; function initialize() { sourceEl = document.querySelector("#source-str"); resultEl = document.querySelector("#result"); separatorEl = document.querySelector("#separator-input"); emptyArrEl = document.querySelector("#empty-arr-input"); document.querySelector("#convert-src").addEventListener("click", convertClick); } function convertClick() { const sourceStr = sourceEl.value; const sepChar = separatorEl.value; const emptyArr = emptyArrEl.checked; const convertResult = convert(sourceStr, sepChar, emptyArr); if (!Array.isArray(convertResult)) { console.error(convertResult); return; } const json = JSON.stringify(resultArr, undefined, 2); resultEl.textContent = json; //resultEl.scrollIntoView({ behavior: "smooth" }); } function convert(sourceStr, sepChar, emptyArr) { if (!sourceStr) { return { message: "An appsettings.json array string was not entered into the text area" }; } // Remove whitespace from both ends of the source string sourceStr = sourceStr.trim(); // Add an open curly bracket ('{') if this character // is not at the beginning of the trimmed string. // Assume a close curly bracket does not exist // if an opening curly bracket does not exist. if (sourceStr.indexOf("{") !== 0) { sourceStr = "{" + sourceStr + "}"; } // Convert the source string into an object using // 'JSON.parse()' within a 'try...catch' statement. let srcObj; try { srcObj = JSON.parse(sourceStr); } catch (error) { return error; } resultArr = []; // If the separator input control returns an empty value, // then default to a double underscore ("__") // (a multiplataform syntax on Azure App Service). sep = !sepChar ? "__" : sepChar; setValToEmpty = emptyArr; parseObj(srcObj, ""); return resultArr; } // Use template literals with backticks (`${value}`) // to convert non-strings (e.g. boolean, numbers) to string. function parseObj(obj) { // Set the 'arrName' variable to the key for (let [arrName, value] of Object.entries(obj)) { if (Array.isArray(value)) { iterateNamedArray(arrName, value); } } } function iterateNamedArray(arrName, value) { for (let i = 0; i < value.length; i++) { if (typeof value[i] === "object") { // Array of objects if (setValToEmpty) { const name = `${arrName}${sep}${i}`; resultArr.push({ name: name, value: "" }); continue; } // Iterate entries of 'value[i]' object for (let [propName, propValue] of Object.entries(value[i])) { const name = `${arrName}${sep}${i}${sep}${propName}`; resultArr.push({ name: name, value: `${propValue}` }); } } else { // Array of strings, integers, booleans const name = `${arrName}${sep}${i}`; if (setValToEmpty) { value[i] = ""; } resultArr.push({ name: name, value: `${value[i]}` }); } } }
body {
  display: grid;
  grid-gap: 0.5rem;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

h4 {
  margin: 0;
  padding: 0
}

#source-str {
  width: 80%;
  height: 10rem;
  padding: 0.5rem 1rem;
  border: 1px solid #ddd;
  font-size: 0.95rem;
  white-space: pre;
  margin-bottom: 1rem;
}

#result {
  background: #f7f7f7;
  border: 1px solid #ddd;
  border-left: 3px solid #1c8dc3;
  margin: 0;
  padding: 0.5rem 1rem;
  box-sizing: border-box;
  font-size: 1rem;
  line-height: 1.6;
  width: 90%;
  min-height: 15rem;
  white-space: pre-wrap;
}

#controls {
  display: flex;
  flex-direction: row;
  gap: 2rem;
  align-items: center;
  align-content: center;
  margin-bottom: 1rem;
}

#convert-src {
  background-color: #1c8dc3;
  color: #fff;
  padding: 0.5rem;
  border: unset;
  width: fit-content;
}

label {
  display: grid;
  grid-auto-flow: column;
  justify-content: start;
  grid-gap: .5rem;
  align-items: center;
}

#separator-input {
  width: 2rem;
  height: 1.5rem;
  text-align: center;
  font-weight: bold;
  display: grid;
  border: 1px solid #ddd;
}

#empty-arr-input {
  width: 1.2rem;
  height: 1.2rem;
}
<!DOCTYPE html>
<html lang='en'>

<head>
  <meta charset='utf-8' />
  <title>Convert appsettings.json to Azure bulk import - Simple</title>
  <link href="~/css/convert-appsettings-simple.css" rel="stylesheet" />
</head>

<body>
  <h4>appsettings.json</h4>
  <textarea id="source-str" title="appsettings JSON text">
"SupportedLanguages": [
  {
    "Code": "en-AU",
    "Name": "English (Australia)"
  },
  {
    "Code": "en-GB",
    "Name": "English (United Kingdom)"
  },
  {
    "Code": "en-US",
    "Name": "English (United States)"
  }
],
"Unsupported": [
  {
    "Code": "fr-FR",
    "Name": "French (France)"
  },
  {
    "Code": "fr-CA",
    "Name": "French (Canada)"
  }
],
"SpellCheckers": [
    "UKEng.dll",
    "AusEng.dll"
]
    </textarea>
  <div id="controls">
    <label>
            <span>Separator</span>
            <input type="text" id="separator-input" value="__" />
        </label>
    <label>
            <span>Empty array</span>
            <input type="checkbox" id="empty-arr-input" />
        </label>
    <button type="button" id="convert-src">Convert</button>
  </div>
  <h4>Azure bulk edit JSON</h4>
  <pre id="result"></pre>
  <script type="module" src="~/js/convert-appsettings-simple.js"></script>
</body>

</html>


-1
投票

应用程序设置中的设置会在运行时注入到您的appsettings.json

中,覆盖现有设置。
 它不会更改 appsettings.json 文件,因为 Azure GUI(连接字符串、应用程序设置)在内部使用环境变量。

这里有一个

类似的帖子

供您参考。您可以在发布期间通过 VSTS 覆盖设置。以下是Colin 的 ALM 角构建和发布工具教程的链接。更详细的可以参考上一篇psycho的回复

如果需要在 VSTS 发布活动期间(在将其发布到 Azure 之前)覆盖 appsettings.json 的值,可以使用 Colin 的 ALM Corner 构建和发布工具。

© www.soinside.com 2019 - 2024. All rights reserved.