如何将JArray格式JSON转换为C#的Settings类对象?
把JArray格式JSON转换为自定义C# Settings类的几种方法
我来帮你搞定这个转换需求~这里有几个实用的方案,你可以根据自己的场景选择:
方法1:手动遍历映射(直观易控,适合简单场景)
这种方法最直接,逐个处理JArray里的每个键值对,明确映射到Settings类的属性,还能灵活处理类型转换和缺省值:
首先确保你引用了Newtonsoft.Json.Linq命名空间,然后写转换方法:
using Newtonsoft.Json.Linq; public static Settings ConvertJArrayToSettings(JArray jArray) { var settings = new Settings(); foreach (JObject jObj in jArray) { var settingName = jObj["name"]?.ToString(); var settingValue = jObj["value"]?.ToString(); switch (settingName?.ToUpperInvariant()) { case "ENABLED": settings.Enabled = string.Equals(settingValue, "Y", StringComparison.OrdinalIgnoreCase); break; case "FILETYPE": settings.FileType = settingValue; break; case "DELIMITER": settings.Delimiter = settingValue; break; case "USESOWNBRANCHCODES": _ = bool.TryParse(settingValue, out var branchCodesVal); settings.UseOwnBranchCodes = branchCodesVal; break; case "USESOWNSKUS": _ = bool.TryParse(settingValue, out var skusVal); settings.UseOwnProductCodes = skusVal; break; case "INTERNALERRORRECIPIENT": settings.InternalContacts = settingValue; break; case "EXTERNALERRORRECIPIENT": settings.ExternalContacts = settingValue; break; // 处理原JSON中没有的属性,可设置默认值或留空 case "ORDERFILESUFFIX": settings.OrderFileSuffix = settingValue ?? ".order"; break; case "RESULTFILESUFFIX": settings.ResultFileSuffix = settingValue ?? ".result"; break; } } return settings; }
优点:逻辑清晰,每个字段的转换都完全可控,能轻松处理特殊格式(比如ENABLED的Y/N转bool),也能灵活处理缺省属性的默认值。
方法2:LINQ to JSON构建字典(简洁高效)
先把JArray转换成键值对字典,再从字典中提取值映射到Settings类,代码更紧凑:
using Newtonsoft.Json.Linq; using System.Linq; public static Settings ConvertJArrayToSettings(JArray jArray) { // 转成忽略大小写的字典,避免大小写不匹配问题 var settingsDict = jArray .ToDictionary( jObj => jObj["name"]?.ToString(), jObj => jObj["value"]?.ToString(), StringComparer.OrdinalIgnoreCase); return new Settings { Enabled = settingsDict.TryGetValue("ENABLED", out var enabledVal) && string.Equals(enabledVal, "Y", StringComparison.OrdinalIgnoreCase), FileType = settingsDict.TryGetValue("FILETYPE", out var fileTypeVal) ? fileTypeVal : null, Delimiter = settingsDict.TryGetValue("DELIMITER", out var delimiterVal) ? delimiterVal : null, UseOwnBranchCodes = settingsDict.TryGetValue("USESOWNBRANCHCODES", out var branchVal) && bool.TryParse(branchVal, out var branchBool) ? branchBool : false, UseOwnProductCodes = settingsDict.TryGetValue("USESOWNSKUS", out var skuVal) && bool.TryParse(skuVal, out var skuBool) ? skuBool : false, InternalContacts = settingsDict.TryGetValue("INTERNALERRORRECIPIENT", out var internalVal) ? internalVal : null, ExternalContacts = settingsDict.TryGetValue("EXTERNALERRORRECIPIENT", out var externalVal) ? externalVal : null, // 给缺省属性设置默认值 OrderFileSuffix = settingsDict.TryGetValue("ORDERFILESUFFIX", out var orderSuffix) ? orderSuffix : ".order", ResultFileSuffix = settingsDict.TryGetValue("RESULTFILESUFFIX", out var resultSuffix) ? resultSuffix : ".result" }; }
优点:代码更简洁,用TryGetValue避免找不到键的异常,忽略大小写的字典也能兼容JSON中name的大小写变化。
方法3:AutoMapper映射(适合复杂/复用场景)
如果你的项目中有很多类似的转换需求,用AutoMapper可以统一配置映射规则,提升代码复用性:
首先安装AutoMapper包:
Install-Package AutoMapper Install-Package AutoMapper.Extensions.Microsoft.DependencyInjection
然后配置映射并使用:
using AutoMapper; using Newtonsoft.Json.Linq; using System.Linq; // 配置映射规则 var mapperConfig = new MapperConfiguration(cfg => { cfg.CreateMap<JArray, Settings>() .ForMember(dest => dest.Enabled, opt => opt.MapFrom(src => src.FirstOrDefault(j => j["name"]?.ToString().Equals("ENABLED", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString() == "Y")) .ForMember(dest => dest.FileType, opt => opt.MapFrom(src => src.FirstOrDefault(j => j["name"]?.ToString().Equals("FILETYPE", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString())) .ForMember(dest => dest.Delimiter, opt => opt.MapFrom(src => src.FirstOrDefault(j => j["name"]?.ToString().Equals("DELIMITER", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString())) .ForMember(dest => dest.UseOwnBranchCodes, opt => opt.MapFrom(src => bool.TryParse(src.FirstOrDefault(j => j["name"]?.ToString().Equals("USESOWNBRANCHCODES", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString(), out var val) ? val : false)) .ForMember(dest => dest.UseOwnProductCodes, opt => opt.MapFrom(src => bool.TryParse(src.FirstOrDefault(j => j["name"]?.ToString().Equals("USESOWNSKUS", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString(), out var val) ? val : false)) .ForMember(dest => dest.InternalContacts, opt => opt.MapFrom(src => src.FirstOrDefault(j => j["name"]?.ToString().Equals("INTERNALERRORRECIPIENT", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString())) .ForMember(dest => dest.ExternalContacts, opt => opt.MapFrom(src => src.FirstOrDefault(j => j["name"]?.ToString().Equals("EXTERNALERRORRECIPIENT", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString())) .ForMember(dest => dest.OrderFileSuffix, opt => opt.MapFrom(src => src.FirstOrDefault(j => j["name"]?.ToString().Equals("ORDERFILESUFFIX", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString() ?? ".order")) .ForMember(dest => dest.ResultFileSuffix, opt => opt.MapFrom(src => src.FirstOrDefault(j => j["name"]?.ToString().Equals("RESULTFILESUFFIX", StringComparison.OrdinalIgnoreCase))?["value"]?.ToString() ?? ".result")); }); // 创建映射器并转换 var mapper = mapperConfig.CreateMapper(); var settings = mapper.Map<Settings>(yourJArrayInstance);
优点:一次配置多次使用,适合大型项目中多个类似的转换场景,代码更整洁。
注意事项
- 如果你用的是
System.Text.Json而不是Newtonsoft.Json,只需要把JArray换成JsonElement,逻辑类似,但Newtonsoft对动态JSON的处理更灵活。 - 类型转换时尽量用
TryParse而不是直接转换,避免因格式错误抛出异常。 - 原JSON中没有
OrderFileSuffix和ResultFileSuffix,记得根据业务需求设置默认值或留空。
内容的提问来源于stack exchange,提问作者r3plica
相关产品推荐
相关产品推荐

