在ASP.NET Core中,JsonConfigurationProvider将从 appsettings.json 加载配置,然后在环境版本 appsettings。{Environment} .json 中读取,基于IHostingEnvironment.EnvironmentName是什么。环境版本可以覆盖基本 appsettings.json 的值。
是否有任何合理的方法来预览生成的被覆盖配置的外观?
很显然,您可以可以编写单元测试,以明确测试元素是否超出了您的期望,但这对于每次更改设置而言都是非常费力的解决方法,需要进行维护。如果您只是想验证自己没有放错括号或拼写错误的元素名称,那不是一个好的解决方案。
返回ASP.NET的web.config转换,您只需在Visual Studio中的转换上单击鼠标右键,然后选择“预览转换”。还有许多其他方法可以在Visual Studio外部预览XSLT转换。即使使用Parameters.xml对web.config进行参数化,您也至少可以执行Web Deploy并检查生成的web.config,以确保其正确显示。
似乎没有任何内置方法可以预览 appsettings。{Environment} .json 对Visual Studio中基本文件的影响。我也无法在VS之外找到任何东西来帮助解决这个问题。尽管JSON覆盖现在已经成为ASP.NET Core不可或缺的一部分,但它似乎并不常见。
答案 0 :(得分:1)
实际上没有办法做到这一点,但是我认为这实际上是如何工作的将有助于您理解原因。
通过config转换,可以对文字文件进行修改,因此可以很容易地对其进行“预览”以显示结果文件。 ASP.NET Core中的配置系统完全不同。
它基本上只是一本字典。在启动期间,每个注册的配置提供程序都按照其注册顺序运行。提供程序读取其配置源(无论是JSON文件,系统环境变量,命令行参数等),然后构建键值对,然后将其添加到主配置“字典”中。 “覆盖”,例如appsettings.{environment}.json
,实际上只是在appsettings.json
提供者之后注册的另一个JSON提供者,它显然使用了不同的源(JSON文件)。由于它是在之后注册的,因此在遇到现有键时,其值将被覆盖,这与添加到字典中的任何内容一样。
换句话说,“预览”将是已完成的配置对象(词典),它由许多不同的来源组成,而不仅仅是这些JSON文件,并且诸如环境变量或命令行参数之类的内容甚至会覆盖环境特定的JSON(因为它们是在此之后注册的),因此您在技术上仍然不知道是否应用了特定于环境的JSON,因为该值可能来自其他来源。
答案 1 :(得分:1)
我发现将appsettings文件加载到JObjects中后,可以使用Json.NET的Merge功能实现预览。
这是一个演示此操作的简单控制台应用程序。提供路径到您的appsettings文件所在的位置,并将预览它们在每种环境中的外观。
static void Main(string[] args)
{
string targetPath = @"C:\path\to\my\app";
// Parse appsettings.json
var baseConfig = ParseAppSettings($@"{targetPath}\appsettings.json");
// Find all appsettings.{env}.json's
var regex = new Regex(@"appsettings\..+\.json");
var environmentConfigs = Directory.GetFiles(targetPath, "*.json")
.Where(path => regex.IsMatch(path));
foreach (var env in environmentConfigs)
{
// Parse appsettings.{env}.json
var transform = ParseAppSettings(env);
// Clone baseConfig since Merge is a void operation
var result = (JObject)baseConfig.DeepClone();
// Merge the two, making sure to overwrite arrays
result.Merge(transform, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Replace
});
// Write the preview to file
string dest = $@"{targetPath}\preview-{Path.GetFileName(env)}";
File.WriteAllText(dest, result.ToString());
}
}
private static JObject ParseAppSettings(string path)
=> JObject.Load(new JsonTextReader(new StreamReader(path)));
虽然这不能保证部署后不会有其他任何配置源不会覆盖它们,但这至少可以让您验证这两个文件之间的交互将得到正确处理。