ASP.NET中基于SQL脚本的HTTP响应反序列化类型转换问题
解决通用API调用中的JSON反序列化类型转换问题
问题场景
有一个接收SQL脚本作为请求体的API端点,响应JSON结构如下:
{ "result": "SQL执行的结果数据", "totalrows": "数据总行数" }
由于SQL语句不同返回的数据结构各异,创建了通用的JSON反序列化模型:
public class QueryResult { public List<object> result { get; set; } public int totalRows { get; set; } }
通过以下代码发送请求并获取数据:
public static async Task<QueryResult> ExecuteQuery(Query query) { var httpClient = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }); var json = JsonConvert.SerializeObject(query); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(AppSetting.url, content); var jsonResult = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<QueryResult>(jsonResult); }
API返回的JSON示例:
{"totalrow":1,"result":[{"Name":"Ali","Age":35}]}
尝试将结果转换为自定义数据模型Name时,抛出如下异常:
NamesCollection= new List<Name>(); var data = await ApiServices.ExecuteQuery(sampleQuery); foreach (var item in data.result) { NamesCollection.Add((Name)item); }
System.InvalidCastException: 'Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Name'
需求:保留通用API调用方法,无需为每个数据模型单独创建方法,解决类型转换问题。
解决方案
方法一:使用泛型类实现强类型反序列化
将通用模型和API调用方法改为泛型,直接在调用时指定目标数据类型,避免后续类型转换:
- 修改泛型版
QueryResult模型
public class QueryResult<T> { public List<T> result { get; set; } // 注意:API返回字段是"totalrow",需添加JsonProperty特性做映射 [JsonProperty("totalrow")] public int totalRows { get; set; } }
- 修改泛型版
ExecuteQuery方法
public static async Task<QueryResult<T>> ExecuteQuery<T>(Query query) { var httpClient = new HttpClient(new HttpClientHandler() { UseDefaultCredentials = true }); var json = JsonConvert.SerializeObject(query); var content = new StringContent(json, Encoding.UTF8, "application/json"); var response = await httpClient.PostAsync(AppSetting.url, content); var jsonResult = await response.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<QueryResult<T>>(jsonResult); }
- 调用时指定目标类型
NamesCollection = new List<Name>(); // 调用时传入Name类型,直接得到强类型结果 var data = await ApiServices.ExecuteQuery<Name>(sampleQuery); // 直接使用强类型集合,无需转换 NamesCollection.AddRange(data.result);
方法二:在现有代码基础上转换JObject
如果不想重构原有通用方法,可利用Newtonsoft.Json的JObject转换能力,在遍历结果时完成类型转换:
NamesCollection = new List<Name>(); var data = await ApiServices.ExecuteQuery(sampleQuery); foreach (var item in data.result) { // 将JObject实例转换为Name类型 var nameModel = ((Newtonsoft.Json.Linq.JObject)item).ToObject<Name>(); NamesCollection.Add(nameModel); }
这种方式无需改动原有API调用逻辑,仅在结果处理环节做转换,适合快速修复场景。
内容的提问来源于stack exchange,提问作者Ali Alfaraj
相关产品推荐
相关产品推荐

