如何修复C#中生成了格式化JSON结果却向调用方返回null的方法
问题排查与修复方案
核心错误:多余的外层foreach循环
你的代码里外层foreach (var categoriesJson in catObj)是完全无意义的冗余逻辑:
- 内部查询已经直接通过
catObj.SelectTokens("Categories[*]")读取了catObj下的Categories数组,根本不需要遍历catObj的根属性 - 如果你的
categories.json根节点下没有可遍历的属性,整个foreach块根本不会执行,静态属性TechList没有被赋值,string类型的默认值就是null,这是你返回null的最核心原因 - 就算能进入循环,每次迭代都会覆盖
TechList的值,最终结果只会是最后一次迭代的查询结果,不符合预期
其他可能导致异常的问题
- 关联查询无匹配:两个JSON数据中,
Categories和TechTypes下的CategoryID没有匹配项,或者匹配项不满足where后的过滤条件,会导致查询结果为空 - 类型转换异常:你代码中直接将
c["GameVersion"]和t["GameVersion"]强制转换为char,如果JSON中该字段存储的是字符串类型(比如值为"A"而非单个字符),会触发强制类型转换异常,若上层逻辑吞了异常,也会导致方法没有正常返回有效值 - 静态属性残留问题:
TechList是静态属性,多次调用方法时会残留上一次的结果,建议改为方法内的局部变量 - 文件路径问题:建议用
Path.Combine拼接路径,避免不同系统下路径分隔符不兼容的问题
修复后代码
using System.Linq; using System.IO; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace AutosortLockers { class GetLists { public static string GetTechType() { // 提前校验文件存在性,避免抛异常 string modPath = Mod.GetModPath(); string catPath = Path.Combine(modPath, "categories.json"); string ttPath = Path.Combine(modPath, "techtypes.json"); if (!File.Exists(catPath) || !File.Exists(ttPath)) { // 返回空数组避免null return "[]"; } JObject catObj = JObject.Load(new JsonTextReader(File.OpenText(catPath))); JObject ttObj = JObject.Load(new JsonTextReader(File.OpenText(ttPath))); // 过滤变量提到逻辑外,避免重复初始化 var gameVersions = new HashSet<string> { "A", "2" }; var categoryIDs = new HashSet<string> { "metals", "tablets" }; var useInMod = new HashSet<bool> { true }; // 移除多余的外层foreach var query = from c in catObj.SelectTokens("Categories[*]").OfType<JObject>() join t in ttObj.SelectTokens("TechTypes[*]") on (string)c["CategoryID"] equals (string)t["CategoryID"] where categoryIDs.Count > 0 ? useInMod.Contains((bool)c["UseInMod"]) && gameVersions.Contains((string)c["GameVersion"]) && gameVersions.Contains((string)t["GameVersion"]) && categoryIDs.Contains((string)c["CategoryID"]) : useInMod.Contains((bool)c["UseInMod"]) && gameVersions.Contains((string)c["GameVersion"]) && gameVersions.Contains((string)t["GameVersion"]) select new { CategoryDescription = c["CategoryDescription"], CategoryID = c["CategoryID"], TechName = t["TechName"], TechType = t["TechType"], TechID = t["TechID"], GameVersion = t["GameVersion"] }; // 直接返回序列化结果,不需要静态属性中转 return JsonConvert.SerializeObject(query.ToArray(), Formatting.Indented); } } }
内容的提问来源于stack exchange,提问作者Vijer
相关产品推荐
相关产品推荐

