解析HTTP响应JSON转对象时遇Newtonsoft.Json.JsonReaderException错误求助
错误详情
Error : Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing number: G. Path '', line 1, position 7.
at Newtonsoft.Json.JsonTextReader.ReadNumberCharIntoBuffer(Char currentChar, Int32 charPos)
at Newtonsoft.Json.JsonTextReader.ReadNumberIntoBuffer()
at Newtonsoft.Json.JsonTextReader.ParseNumber(ReadType readType)
at Newtonsoft.Json.JsonTextReader.ParseValue()
at Newtonsoft.Json.JsonReader.ReadAndMoveToContent()
at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Pando.DataLayer.Repositories.DBSRepository.DBSAPIint() in D:\agent_work\242\s\Application\DBS.DataLayer\Repositories\DBSRepository.cs:line 137
问题代码
HttpContent httpContent = new StringContent(encryptedMessage); httpContent.Headers.ContentType = new MediaTypeHeaderValue("text/plain"); var response = await httpClient.PostAsync(apiUrl, httpContent); string responseMsg1 = await response.Content.ReadAsStringAsync(); HttpStatusCode statusCode = response.StatusCode; string status = response.StatusCode.ToString(); int codes = ((int)response.StatusCode); //var dataObject = (JObject)JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); //Json is capture in dataobject var dataObject = JsonConvert.DeserializeObject(responseMsg1); //Json is capture in dataobject var responseCode = codes.ToString(); var Jsondata = dataObject.ToString(); var error1 = new SqlParameter("@errorDesc", Jsondata); int Qryres1 = dbc.Database.ExecuteSqlRaw("exec[dbo].[DBSlog] @errorDesc", error1); //EOC 19-06-23 //var json = new SqlParameter("@json", jsonData); //var response = new SqlParameter("@responseCode", responseCode); var Json = new SqlParameter("@Jsondata", Jsondata); var msgid = new SqlParameter("@msgid", od.msgId); //var Status = new SqlParameter("@status", status); //var Ack_type = new SqlParameter("@type", type); //updating the status of data dbc.Database.ExecuteSqlRaw("exec[dbo].[Usp_JsonToTable] @Jsondata @msgid", Json,msgid); response.EnsureSuccessStatusCode();
问题分析
错误提示明确指出:解析数字时在第1行第7位遇到了意外字符G。这说明你尝试反序列化的responseMsg1不是合法的JSON字符串,可能的原因包括:
- API返回的是错误响应(如500错误页、纯文本错误信息)而非JSON
- 响应内容是加密后的原始数据,未经过解密处理
- 响应存在编码问题,导致字符串格式异常
- API返回的内容本身不符合JSON规范
解决方案
1. 排查原始响应内容
在反序列化前添加日志或打印,确认responseMsg1的实际内容,这是定位问题的核心:
string responseMsg1 = await response.Content.ReadAsStringAsync(); // 临时输出原始响应,可替换为日志记录 Console.WriteLine($"Raw API Response: {responseMsg1}");
通过这一步能直接看到返回的内容是否为合法JSON,比如如果返回的是类似"500GatewayError"这类带G的字符串,就能明确问题所在。
2. 提前校验HTTP响应状态
原代码中response.EnsureSuccessStatusCode()放在最后,导致即使API返回错误状态(如400、500),仍会尝试解析非JSON内容。应提前校验:
var response = await httpClient.PostAsync(apiUrl, httpContent); // 先确保请求成功,避免处理错误响应 response.EnsureSuccessStatusCode(); string responseMsg1 = await response.Content.ReadAsStringAsync();
3. 添加反序列化异常捕获
在反序列化逻辑外包裹try-catch,记录详细错误信息,便于排查:
var dataObject = default(JObject); try { dataObject = JsonConvert.DeserializeObject<JObject>(responseMsg1); } catch (JsonReaderException ex) { // 记录错误和原始响应,方便定位 Console.WriteLine($"Deserialization Failed: {ex.Message}, Raw Response: {responseMsg1}"); throw; // 或根据业务逻辑做降级处理 }
4. 确认响应解密逻辑(如果需要)
如果API要求请求加密,返回的响应可能也是加密状态,需要先解密responseMsg1,再进行JSON反序列化。
修正后的完整代码示例
HttpContent httpContent = new StringContent(encryptedMessage); httpContent.Headers.ContentType = new MediaTypeHeaderValue("text/plain"); var response = await httpClient.PostAsync(apiUrl, httpContent); // 提前校验响应状态 response.EnsureSuccessStatusCode(); string responseMsg1 = await response.Content.ReadAsStringAsync(); // 临时输出原始响应,排查问题用 Console.WriteLine($"Raw API Response: {responseMsg1}"); HttpStatusCode statusCode = response.StatusCode; string status = response.StatusCode.ToString(); int codes = ((int)response.StatusCode); var dataObject = default(JObject); try { dataObject = JsonConvert.DeserializeObject<JObject>(responseMsg1); } catch (JsonReaderException ex) { Console.WriteLine($"Deserialization Error: {ex.Message}, Raw Response: {responseMsg1}"); throw; } var responseCode = codes.ToString(); var Jsondata = dataObject.ToString(); var error1 = new SqlParameter("@errorDesc", Jsondata); int Qryres1 = dbc.Database.ExecuteSqlRaw("exec[dbo].[DBSlog] @errorDesc", error1); var Json = new SqlParameter("@Jsondata", Jsondata); var msgid = new SqlParameter("@msgid", od.msgId); // 注意存储过程参数间添加逗号分隔 dbc.Database.ExecuteSqlRaw("exec[dbo].[Usp_JsonToTable] @Jsondata, @msgid", Json, msgid);
内容的提问来源于stack exchange,提问作者Yash

