JsonConvert.DeserializeObject无法解析API返回的DataSet JSON,如何解决?
问题
使用JsonConvert.DeserializeObject将API返回的JSON反序列化为DataSet时无法获取任何数据。
API返回的JSON响应:
{"Table": [{"newcust": 0}],"Table1": [{"ymon": "201706","ttlsalamtmon": 0.000000,"collamtmon": 0.000000,"tarcollamt": 0.000000,"targtsaleamt": 0.000000}],"Table2": [{"schdate": "2017-06-06T00:00:00","ttlsalamtday": 0.000000,"collamtday": 0.000000,"percn": 0.0000000000000000}],"Table3": [{"ymon": "31-May","yearmon": "2017-05-31T00:00:00","ttlsalamt": 0.000000,"collamt": 0.000000},{"ymon": "01-Jun","yearmon": "2017-06-01T00:00:00","ttlsalamt": 0.000000,"collamt": 0.000000},{"ymon": "02-Jun","yearmon": "2017-06-02T00:00:00","ttlsalamt": 0.000000,"collamt": 0.000000},{"ymon": "03-Jun","yearmon": "2017-06-03T00:00:00","ttlsalamt": 0.000000,"collamt": 0.000000},{"ymon": "04-Jun","yearmon": "2017-06-04T00:00:00","ttlsalamt": 0.000000,"collamt": 0.000000},{"ymon": "05-Jun","yearmon": "2017-06-05T00:00:00","ttlsalamt": 0.000000,"collamt": 0.000000},{"ymon": "06-Jun","yearmon": "2017-06-06T00:00:00","ttlsalamt": 0.000000,"collamt": 0.000000}],"Table4": [],"Table5": [{"ymon": "201701","yearmon": "Jan ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201702","yearmon": "Feb ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201703","yearmon": "Mar ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201704","yearmon": "Apr ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201705","yearmon": "May ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201706","yearmon": "Jun ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201707","yearmon": "Jul ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201708","yearmon": "Aug ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201709","yearmon": "Sep ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201710","yearmon": "Oct ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201711","yearmon": "Nov ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000},{"ymon": "201712","yearmon": "Dec ' 2017","ttlsalamt": 0.000000,"collamt": 0.000000,"targtsaleamt": 0.000000,"tarcollamt": 0.000000}],"Table6": [{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000}],"Table7": [{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000}],"Table8": [{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000}],"Table9": [{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000},{"sirdesc": "None","suamt": 0.000000}]}
调用API的代码:
internal class SalesDashService { Constants constant = new Constants(); DataSet SalesDashBoardData = new DataSet(); public async Task<DataSet> GetSalesDashInfo(string comcode) { try { string url = constant.Url + "/api/Mis/ShowSalesDashBoard?comcod=3101&date1=06-Jun-2017&typedata=3"; using (HttpClient client = new HttpClient()) { client.BaseAddress = new Uri(url); var response = await client.GetAsync(url).ConfigureAwait(false); if (response.IsSuccessStatusCode) { var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false); SalesDashBoardData = JsonConvert.DeserializeObject<DataSet>(data); } } } catch (Exception e) { return null; } return SalesDashBoardData; } }
后端已确认返回DataSet格式数据,但无法获取数据或DataSet对象,求解决方法。
解决方法
1. 修正JSON与DataSet的格式匹配问题
Newtonsoft.Json默认反序列化DataSet时,要求JSON符合标准DataSet序列化结构:根节点需包含"Tables"数组,每个表节点需明确"TableName"和"Rows"数组。当前返回的JSON直接以Table、Table1等作为顶级键,和默认格式不匹配,可通过两种方式解决:
方式一:后端调整输出格式
将JSON改为标准DataSet结构,示例:
{ "Tables": [ { "TableName": "Table", "Rows": [{"newcust": 0}] }, { "TableName": "Table1", "Rows": [{"ymon": "201706", "ttlsalamtmon": 0.000000, ...}] } ] }
方式二:前端自定义反序列化逻辑
解析JSON对象,将每个顶级键对应的数据转为DataTable,再添加到DataSet中:
var jsonObj = JObject.Parse(data); DataSet ds = new DataSet(); foreach (var prop in jsonObj.Properties()) { DataTable dt = prop.Value.ToObject<DataTable>(); dt.TableName = prop.Name; ds.Tables.Add(dt); } SalesDashBoardData = ds;
2. 修复HttpClient使用错误
当前代码同时设置BaseAddress和在GetAsync中传入完整URL,会导致请求地址拼接错误,二选一即可:
// 写法一:设置BaseAddress,GetAsync传入相对路径 using (HttpClient client = new HttpClient()) { client.BaseAddress = new Uri(constant.Url); var response = await client.GetAsync("/api/Mis/ShowSalesDashBoard?comcod=3101&date1=06-Jun-2017&typedata=3").ConfigureAwait(false); // 后续逻辑 } // 写法二:直接传入完整URL,不设置BaseAddress using (HttpClient client = new HttpClient()) { var response = await client.GetAsync(url).ConfigureAwait(false); // 后续逻辑 }
3. 完善异常排查
当前catch块直接返回null,无法定位具体错误,建议添加日志记录:
catch (Exception e) { Console.WriteLine($"请求或反序列化错误:{e.Message}\n{e.StackTrace}"); // 或写入日志文件 return null; }
4. 验证数据完整性
在反序列化前,打印或记录data变量内容,确认和Postman返回的JSON一致,排除数据传输过程中被篡改或截断的问题。
内容的提问来源于stack exchange,提问作者Md. Shamsul Arefin Khan
相关产品推荐
相关产品推荐

