ASP.NET Core 6短信通知功能中Newtonsoft.Json.JsonReaderException异常的解决方法
ASP.NET Core 6短信通知功能中Newtonsoft.Json.JsonReaderException异常的解决方法
这个异常的核心原因很明确:你尝试反序列化的内容不是有效的JSON格式,而是以<开头的HTML内容(大概率是接口返回的错误页面,比如500内部错误、400参数错误的提示页面)。咱们一步步来解决这个问题:
1. 先搞清楚接口到底返回了什么
在反序列化之前,先把返回的原始内容打出来看看,这样能直接定位问题。修改你的SendSmsAsync方法,在反序列化前添加日志或者调试输出:
private async Task<bool> SendSmsAsync(string phoneNumber, string subject, string smsTemplate) { var requestModel = new SendSmsDto { Mobile = phoneNumber, SmsTemplate = smsTemplate, Subject = subject }; var notificationResponse = await _dataAccess.SmsNotificationAsync(requestModel); var notificationResult = await notificationResponse.Content.ReadAsStringAsync(); // 调试阶段先打印内容,或者用日志框架记录下来 Console.WriteLine("接口返回原始内容:" + notificationResult); // 生产环境建议用ILogger记录:_logger.LogInformation("SMS接口返回内容:{Content}", notificationResult); try { var result = JsonConvert.DeserializeObject<NotifyRequestResponse>(notificationResult); return result.ResponseCode == "00"; } catch (JsonReaderException ex) { _logger.LogError(ex, "反序列化SMS接口返回内容失败,原始内容:{Content}", notificationResult); return false; } }
运行后你就能看到,返回的是不是HTML错误页,比如<html><body>500 Internal Server Error</body></html>这类内容。
2. 先检查HTTP响应状态码
第三方接口在请求失败时(比如参数错误、权限问题),通常会返回非2xx的状态码,同时返回HTML错误页。所以在处理响应前,先判断请求是否成功:
var notificationResponse = await _dataAccess.SmsNotificationAsync(requestModel); // 先判断请求是否成功 if (!notificationResponse.IsSuccessStatusCode) { var errorContent = await notificationResponse.Content.ReadAsStringAsync(); _logger.LogError("SMS通知请求失败,状态码:{StatusCode},错误内容:{ErrorContent}", notificationResponse.StatusCode, errorContent); return false; } // 只有请求成功时才继续反序列化 var notificationResult = await notificationResponse.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject<NotifyRequestResponse>(notificationResult);
这样能提前拦截失败的请求,避免进入反序列化的错误流程。
3. 检查请求参数的合法性
从你调用SendSmsAsync的代码来看,是直接用payload的字段拼接短信内容,要确认这些字段是否有null值,或者格式不符合第三方接口的要求:
- 比如
PhoneNo是否是正确的格式(有没有加国家码,比如+86)? amount是decimal类型,转字符串会不会有格式问题?- 有没有必填字段没传(比如
SendSmsDto里是否还有其他必填属性你没赋值)?
另外,建议把短信内容的拼接改成更简洁的字符串插值,减少拼接错误:
var smsContent = $"You sent{Environment.NewLine}" + $"Amount: {payload.amount}{Environment.NewLine}" + $"Receiver: {payload.Receiver}{Environment.NewLine}" + $"PIN: {payload.Pin}{Environment.NewLine}" + $"RegNo: {payload.RegNo}"; var smsSenderValidityResult = await SendSmsAsync(payload.PhoneNo, "MyApp", smsContent);
4. 验证第三方接口的返回规则
有些接口的设计是:成功时返回JSON,失败时返回HTML,这时候你需要根据接口文档,针对错误状态码做特殊处理。比如如果状态码是400,可能需要解析HTML里的错误信息,或者联系接口提供商确认返回格式。
5. 用工具直接测试接口
如果上面的步骤还没找到问题,建议用Postman、curl这类工具,直接模拟你的请求参数调用第三方短信接口,看看返回的内容是什么。这样能快速区分是你的代码问题,还是接口本身的问题。
备注:内容来源于stack exchange,提问作者Bami
相关产品推荐
相关产品推荐

