动态生成settings.json时嵌套类型转换异常问题求助
泛型配置类动态更新settings.json时嵌套类型转换异常
我需要在类库中实现一个类,能够从泛型对象T动态生成settings.json文件,并且当T的结构变更时自动增删对应的属性。目前代码可以正常创建JSON文件,但修改T后运行时抛出异常:
System.ArgumentException: 'Object of type 'System.Text.Json.JsonElement' cannot be converted to type 'Common.Settings.JWTSecuritySettings'.'
该异常与T中的嵌套配置类有关(例如AppSettings包含的JWTSecuritySettings、DBConnectionSettings)。尝试移除UpdateJsonObject方法中的if判断逻辑后,问题仍未解决,反而出现了其他错误。
核心代码
Settings类实现
using Microsoft.Extensions.Options; using System.Reflection; using System.Text.Json; namespace Common.Settings { public static class Settings { public static string FilePath { get; private set; } public static string FileName { get; private set; } public static T UseSettings<T>(this IServiceCollection services, Action<Options>? configureOptions) where T : class, new() { var options = new Options(); configureOptions?.Invoke(options); FilePath = options.Path; FileName = options.FileName; var filePath = Path.Combine(options.Path, options.FileName); if (!File.Exists(filePath)) { Directory.CreateDirectory(options.Path); var settings = CreateDefaultSettings<T>(); var defaultSettings = JsonSerializer.Serialize(settings); File.WriteAllText(filePath, defaultSettings); } var json = File.ReadAllText(filePath); var rootElement = JsonDocument.Parse(json).RootElement; var properties = typeof(T).GetProperties(); var mismatchFound = false; foreach (var property in properties) { if (!rootElement.TryGetProperty(property.Name, out var propertyElement)) { mismatchFound = true; Console.WriteLine($"Property '{property.Name}' not found in {options.FileName}"); rootElement = UpdateJsonObject<T>(rootElement, filePath); continue; } } if (mismatchFound) { Console.WriteLine($"** Property mismatches found in {options.FileName} JSON configuration. The missing properties were added to {options.FileName}. **"); } var deserializedSettings = JsonSerializer.Deserialize<T>(json); services.AddSingleton(deserializedSettings); return deserializedSettings; } private static T CreateDefaultSettings<T>() where T : class, new() { var settings = new T(); var properties = typeof(T).GetProperties(); foreach (var property in properties) { if (property.PropertyType.IsClass && property.PropertyType != typeof(string)) { var nestedSettings = typeof(Settings).GetMethod("CreateDefaultSettings", BindingFlags.NonPublic | BindingFlags.Static) .MakeGenericMethod(property.PropertyType) .Invoke(null, null); property.SetValue(settings, nestedSettings); } } return settings; } private static JsonElement UpdateJsonObject<T>(JsonElement element, string filePath) where T : class, new() { var settings = new T(); var properties = typeof(T).GetProperties(); foreach (var property in properties) { Console.WriteLine(property); if (property.PropertyType.IsClass && property.PropertyType != typeof(string)) { var nestedSettings = typeof(Settings).GetMethod("UpdateJsonObject", BindingFlags.NonPublic | BindingFlags.Static) .MakeGenericMethod(property.PropertyType) .Invoke(null, [element, filePath]); if (element.TryGetProperty(property.Name, out var ele)) { property.SetValue(settings, ele); } else { property.SetValue(settings, nestedSettings); } } } var defaultSettings = JsonSerializer.Serialize(settings); File.WriteAllText(filePath, defaultSettings); return JsonDocument.Parse(defaultSettings).RootElement; } } public class Options { public string Path { get; set; } = "config"; public string FileName { get; set; } = "settings.json"; } }
嵌套配置类定义
public class AppSettings{ public string Servicename { get; set; } public string AppDomain { get; set; } public JWTSecuritySettings JWTSettings { get; set; } public DBConnectionSettings DBSettings { get; set; } public string TenantDBEncryptionKey { get; set; } } public class JWTSecuritySettings { public string PrivateKey { get; set; } public string PublicKey { get; set; } public string Issuer { get; set; } = "http://localhost:5001"; } public class DBConnectionSettings { public string ConnectionString { get; set; } ="Host=localhost;Database=DEVDB;Username=postgres;Password=post"; public string DBName { get; set; } }
内容的提问来源于stack exchange,提问作者Flubio
相关产品推荐
相关产品推荐

