[英]Unable to read json comes from Web API in C#
無法將 webapi 值讀取到列表對象。 請查看鏈接http://prntscr.com/lcmw7q 中的屏幕截圖值。
錯誤是Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (eg {"name":"value"}) 到 type 'System.Collections.Generic.List`1[StudentProfileClient.StudentInfo]' 因為該類型需要一個JSON 數組(例如 [1,2,3])以正確反序列化。 要修復此錯誤,請將 JSON 更改為 JSON 數組(例如 [1,2,3])或更改反序列化類型,使其成為正常的 .NET 類型(例如,不是像整數這樣的原始類型,而不是像這樣的集合類型)可以從 JSON 對象反序列化的數組或列表)。 JsonObjectAttribute 也可以添加到類型中以強制它從 JSON 對象反序列化。 路徑“數據”,第 2 行,位置 10。
class StudentInfo
{
public string cellPhone { get; set; }
public string gender { get; set; }
public string dateOfBirth { get; set; }
}
class RootClass
{
public int TotalCount { get; set; }
public List<StudentInfo> stdinfo { get; set; }
}
static async Task GetData()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://203.81.70.102:8092/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response;
response = await client.GetAsync("control/qZkNkcGgWq6PiVbJzQ2=/student-profiles");
if (response.IsSuccessStatusCode)
{
List<StudentInfo> RootClass = new List<StudentInfo>();
RootClass = await response.Content.ReadAsAsync<List<StudentInfo>>();
}
}
}
您不能使用 JsonConvert.DeserializeObject 從 API 響應中直接反序列化。 ——
JObject jsonResponse = JObject.Parse(jsonString);
JObject objResponse = (JObject)jsonResponse["response"];
Dictionary<string, JArray> _Data = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, JArray>>(objResponse.ToString());
不要將 RootClass 聲明為 List,而是使用:
var RootClass = 等待 response.Content.ReadAsAsync()
在行中放置一個斷點,並檢查從 API 返回的類型。 由於 var 將接受任何內容,您可以檢查響應。 基本上,您的錯誤表明您正在嘗試將 CAST 轉換為無效類型,因此反序列化無法正常工作。
似乎返回的對象是一個數組,也許您需要獲取該數組並將其轉換為列表,或者甚至是與您期望的對象完全不同的對象,具有其他屬性等...
解決的最佳方法 ->調試,並確保您使用正確的類型進行反序列化
1) 通過在Newtonsoft.json
使用JObject
。
在包管理器控制台中鍵入以下命令。
Install-Package Newtonsoft.Json
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
JObject jObject = JObject.Parse(json);
List<StudentInfo> studentInfos = jObject["data"].ToObject<List<StudentInfo>>();
}
輸出:
2) 不使用Newtonsoft.json
。
在包管理器控制台中鍵入以下命令。
Install-Package Microsoft.AspNet.WebApi.Client
if (response.IsSuccessStatusCode)
{
RootClass rootClass = await response.Content.ReadAsAsync<RootClass>();
List<StudentInfo> studentInfos = rootClass.data;
}
輸出:
所以你的課程將是
public class StudentInfo
{
public int sl { get; set; }
public string studentId { get; set; }
public string studentName { get; set; }
public string school { get; set; }
public string program { get; set; }
public string fatherName { get; set; }
public string motherName { get; set; }
public string cellPhone { get; set; }
public string gender { get; set; }
public string dateOfBirth { get; set; }
}
public class RootClass
{
public List<StudentInfo> data { get; set; }
public string message { get; set; }
public int total { get; set; }
}
簡單的解決方案,你需要一個包裝器
這在實踐中是什么樣子的? 它只是意味着返回對象列表的 API 將列表包裝在頂級對象中。 例如,假設您的 API 中有一個 Person 數據類型。 如果您 GET 一個 Person,您最終可能會得到以下 JSON 響應:
{ "name": "John Smith" }
到目前為止一切都很好。 但是如果你想要一個列表而不是一個列表呢? 最直觀的方式可能如下:
[{"name": "John Smith"}, {"name": "Jane Smith"}]
但這正是我們需要避免的情況。 因此,我們需要為這樣的列表使用頂級對象,並具有單個數據屬性:
{"data": [{"name": "John Smith"}, {"name": "Jane Smith"}]}
所以.....
Class Students{
public List<StudentInfo> roots{get;set;}
}
保留你的學生班級,添加我班級的學生,然后反序列化;
所以你有一個叫做 RootClass 的類。 您有一個名為 StudentInfo 的類。
你希望得到哪一個? 似乎你得到了完全不同的東西。 正如我在這里看到的, https: //prnt.sc/lcnlho ,您應該創建一個新類(或更改 RootClass 結構),如下所示
class ResponseContainer
{
public List<StudentInfo> data { get; set; }
}
而不是直接反序列化到 List,你應該反序列化到這個 ResponseContainer 類:
var response = await response.Content.ReadAsAsync<ResponseContainer>();
ps 如果你想使用你的 RootClass,你應該將屬性 stdinfo 重命名為“data”,或者像這樣添加 JsonProperty 屬性:
class RootClass
{
public int TotalCount { get; set; }
[JsonProperty(PropertyName = "data")]
public List<StudentInfo> stdinfo { get; set; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.