如何使用前缀语法从appsettings.json获取Serilog指定WriteTo对象
如何通过前缀语法从appsettings.json的Serilog配置中筛选特定WriteTo对象?
配置片段:
"Serilog": { "Using": [ "Serilog.Enrichers.Thread", "Serilog.Enrichers.Process", "Serilog.Enrichers.MachineName", "Serilog.Enrichers.FromLogContext" ], "Enrich": [ "FromLogContext", "WithMachineName", "WithProcessId", "WithThreadId" ], "MinimumLevel": { "Default": "Information", "Override": { "Microsoft": "Warning", "System": "Warning" } }, "WriteTo": [ { "Name": "Console", "Args": { "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}" } }, { "Name": "ApplicationInsights", "Args": { "instrumentationKey": "your-instrumentation-key", "restrictedToMinimumLevel": "Information" } }, { "Name": "Seq", "Args": { "serverUrl": "https://localhost:5341/", "apiKey": "" } } ] }
我尝试用以下代码获取可筛选的数组,但返回的是三个空对象:
var ary = _config.GetSection("Serilog:WriteTo").GetChildren();
希望能用类似Serilog:WriteTo:Name='Seq'的前缀语法直接定位到该配置段并提取值,请问是否有这样的语法实现,或者更优的解决方案?
解决方案
.NET配置系统本身不支持直接通过带条件的前缀语法筛选数组元素,但可以通过以下几种方式实现需求:
1. 绑定到强类型对象后筛选
先定义与配置结构匹配的类,将整个WriteTo数组绑定为强类型列表,再通过LINQ筛选目标项:
// 定义对应配置类 public class SerilogWriteToItem { public string Name { get; set; } public SerilogWriteToArgs Args { get; set; } } public class SerilogWriteToArgs { public string OutputTemplate { get; set; } public string InstrumentationKey { get; set; } public string RestrictedToMinimumLevel { get; set; } public string ServerUrl { get; set; } public string ApiKey { get; set; } } // 绑定并筛选 var writeToItems = _config.GetSection("Serilog:WriteTo").Get<List<SerilogWriteToItem>>(); var seqConfig = writeToItems?.FirstOrDefault(item => item.Name == "Seq"); if (seqConfig != null) { var seqServerUrl = seqConfig.Args.ServerUrl; // 处理Seq配置 }
2. 手动遍历子节点筛选
你之前得到空对象是因为GetChildren()返回的是数组中每个元素的配置节点,需要从节点中读取具体属性值,而非直接将节点视为对象。可以遍历这些节点并筛选:
var writeToSections = _config.GetSection("Serilog:WriteTo").GetChildren(); IConfigurationSection seqSection = null; foreach (var section in writeToSections) { var name = section.GetValue<string>("Name"); if (name == "Seq") { seqSection = section; break; } } if (seqSection != null) { var serverUrl = seqSection.GetValue<string>("Args:serverUrl"); var apiKey = seqSection.GetValue<string>("Args:apiKey"); // 提取所需配置值 }
3. 封装扩展方法复用
如果需要频繁筛选配置数组,可以封装一个扩展方法简化操作:
public static class ConfigurationExtensions { public static IConfigurationSection GetArraySectionByKey(this IConfiguration config, string arrayPath, string keyName, string keyValue) { var arraySection = config.GetSection(arrayPath); foreach (var itemSection in arraySection.GetChildren()) { var value = itemSection.GetValue<string>(keyName); if (value == keyValue) { return itemSection; } } return null; } } // 使用示例 var seqSection = _config.GetArraySectionByKey("Serilog:WriteTo", "Name", "Seq"); if (seqSection != null) { // 处理配置 }
内容的提问来源于stack exchange,提问作者dinotom
相关产品推荐
相关产品推荐

