簡體   English   中英

無法讀取來自 C# 中的 Web API 的 json

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM