Unity中用JsonNet-Lite反序列化JSON遇额外文本错误但JSONLint验证有效
我之前在Unity用JsonNet-Lite的时候也踩过类似的坑,明明JSONLint显示有效,但就是报“反序列化后发现额外文本”的错,结合你的情况,给你几个排查方向:
1. 清理JSON中的隐性空白/不可见字符
很多时候数据源返回的JSON末尾会多出来换行符、制表符,甚至是UTF-8 BOM这种肉眼看不到的字符——JSONLint会自动忽略这些,但JsonNet-Lite的校验会更严格。
你可以在反序列化前先对字符串做预处理:
string rawJson = GetJsonFromSource(); // 先去掉首尾空白 rawJson = rawJson.Trim(); // 再移除所有非打印字符(比如控制字符) rawJson = System.Text.RegularExpressions.Regex.Replace(rawJson, @"[\x00-\x1F\x7F]", ""); // 额外检查UTF-8 BOM if (rawJson.StartsWith("\ufeff")) { rawJson = rawJson.Substring(1); }
2. 确认JSON结构是对象还是数组
你说要反序列化为通用对象再遍历,有可能是数据源返回的是JSON数组,但你用了解析单个对象的方法(比如JObject.Parse或者JsonConvert.DeserializeObject<dynamic>),这时候解析完数组的第一个元素后,剩下的内容就会被当成“额外文本”。
建议先判断JSON的开头字符,再选择对应的解析方式:
if (rawJson.StartsWith("[")) { // 解析为数组 JArray jsonArray = JArray.Parse(rawJson); foreach (JToken item in jsonArray) { // 遍历数组元素 Debug.Log(item.ToString()); } } else if (rawJson.StartsWith("{")) { // 解析为对象 JObject jsonObj = JObject.Parse(rawJson); foreach (var prop in jsonObj.Properties()) { // 遍历对象属性 Debug.Log($"{prop.Name}: {prop.Value}"); } }
3. 注意JsonNet-Lite与完整版的差异
JsonNet-Lite是Newtonsoft.Json的精简版,对某些JSON特性的支持可能不如完整版,比如特殊的转义字符、嵌套极深的结构。如果JSONLint验证通过但Lite版报错,可以试试用完整版Newtonsoft.Json(Unity Asset Store有官方适配版)替换,看是否能解决问题——不过要注意项目的包大小限制。
4. 排查是否存在多个JSON对象拼接的情况
有些数据源会返回多个JSON对象直接拼接(比如{"a":1}{"b":2}),这种情况JSONLint可能只检测第一个对象有效,但实际是两个独立对象,反序列化单个对象时就会报错。如果是这种情况,你需要先把字符串分割成单个JSON对象再分别解析。
总的来说,这个问题大概率是数据源的隐性格式问题,不是你遍历通用对象的思路错了——通过预处理字符串、适配解析方式,基本能解决大部分情况。
内容的提问来源于stack exchange,提问作者Reahreic

