如何用JsonTextReader反序列化JSONP响应(优先不使用字符串)
解决JSONP转JSON的解析问题(Newtonsoft.Json实现)
没问题,我来帮你搞定这个JSONP解析的难题!因为服务返回的是JSONP而非标准JSON,直接反序列化肯定会失败,不过我们可以用Newtonsoft.Json来处理,而且优先满足你想要的流解析需求,避免大字符串的性能损耗。
方案一:基于流的高效解析(推荐)
这个方案不需要把整个数十KB的响应加载到内存里,直接在流层面操作,性能更优。核心思路是用JsonTextReader跳过JSONP的前缀(parseResponse(),直到找到JSON对象的起始标记{,然后再开始反序列化。
代码示例:
using System.IO; using Newtonsoft.Json; // 替换成你获取Web服务响应流的实际代码 using var responseStream = GetWebServiceResponseStream(); using var streamReader = new StreamReader(responseStream); using var jsonReader = new JsonTextReader(streamReader); // 跳过前缀内容,直到读取到JSON对象的起始Token while (jsonReader.Read()) { if (jsonReader.TokenType == JsonToken.StartObject) { break; } } // 开始反序列化到MyType var serializer = new JsonSerializer(); MyType result = serializer.Deserialize<MyType>(jsonReader); // 现在可以正常使用result了 Console.WriteLine($"Total: {result.total}, Lower: {result.lower}, Upper: {result.upper}");
为什么这个方案好用?
- 完全基于流操作,不会把整个大响应加载成字符串,内存占用更低,适合大体积的返回内容
- 不需要手动处理字符串截取,依赖Newtonsoft.Json的Token解析逻辑,更可靠
方案二:安全的字符串解析方案(备选)
如果流处理的方式对你来说有适配成本,也可以用字符串截取的方式,注意要安全处理前缀和后缀,避免嵌套JSON的影响。
代码示例:
using Newtonsoft.Json; using System.Globalization; // 替换成你获取Web服务响应字符串的实际代码 string jsonpResponse = GetWebServiceResponseAsString(); // 找到JSON内容的起始和结束位置 int startPos = jsonpResponse.IndexOf('{'); int endPos = jsonpResponse.LastIndexOf('}'); if (startPos == -1 || endPos == -1) { // 处理解析失败的情况,比如响应格式异常 throw new InvalidDataException("Invalid JSONP response format"); } // 提取纯JSON内容 string pureJson = jsonpResponse.Substring(startPos, endPos - startPos + 1); // 反序列化时注意处理字符串类型的数字(比如示例中的"13,769"和"1") var serializerSettings = new JsonSerializerSettings { // 允许从字符串读取数字类型 NumberHandling = Newtonsoft.Json.Serialization.NumberHandling.AllowReadingFromString, // 处理带逗号的数字字符串(比如"13,769") Culture = CultureInfo.InvariantCulture }; MyType result = JsonConvert.DeserializeObject<MyType>(pureJson, serializerSettings);
关键注意事项
你的MyType类里,total是Decimal类型,但JSON里是带逗号的字符串("13,769"),lower和upper是字符串类型的数字,所以必须在反序列化时配置NumberHandling.AllowReadingFromString,并且指定正确的文化信息来解析带逗号的数字,否则会抛出格式异常。
内容的提问来源于stack exchange,提问作者user6694745
相关产品推荐
相关产品推荐

