我想從我的 ASP.Net Core 應用程式呼叫 API,但回應的格式不是很好:
[
{
page: 1,
pages: 1,
per_page: 50,
total: 2,
sourceid: "2",
sourcename: "World Development Indicators",
lastupdated: "2021-10-28"
},
[
{
indicator: {
id: "NY.GDP.PCAP.KD.ZG",
value: "GDP per capita growth (annual %)"
},
country: {
id: "CA",
value: "Canada"
},
countryiso3code: "CAN",
date: "2020",
value: -6.33904652535297,
unit: "",
obs_status: "",
decimal: 1
},
{
indicator: {
id: "NY.GDP.PCAP.KD.ZG",
value: "GDP per capita growth (annual %)"
},
country: {
id: "CA",
value: "Canada"
},
countryiso3code: "CAN",
date: "2019",
value: 0.43021113414872,
unit: "",
obs_status: "",
decimal: 1
}
]
]
這是 API 網址:https : //api.worldbank.org/v2/country/can/indicator/NY.GDP.PCAP.KD.ZG? format = json & mrv =2
我已經為回應輸入了這些類:
public class WorldBankApiResponseGlobal
{
public int Page { get; set; }
public int Pages { get; set; }
public int Per_Page { get; set; }
public int Total { get; set; }
public string Sourceid { get; set; }
public string Sourcename { get; set; }
}
public class WorldBankApiIdValue
{
public string Id { get; set; }
public string Value { get; set; }
}
public class WorldBankApiResponse
{
public WorldBankApiIdValue Indicator { get; set; }
public WorldBankApiIdValue Country { get; set; }
public int Value { get; set; }
public string Date { get; set; }
public string Countryiso3code { get; set; }
}
但是,由于回應沒有物件的屬性值(即:[{},[]] 而不是 ["data": {}, "indicators": []],我不知道如何正確反序列化 API 呼叫回應...
通常,我會這樣做:
var response = await _client.GetFromJsonAsync<List<WorldBankApiResponseGlobal>>(worldBankApiUrl);
但是有誰知道我會如何處理這種回應型別?
uj5u.com熱心網友回復:
我不知道您是否可以使用GetFromJsonAsync但使用Newtonsoft.Json. 您可以制作一個特殊的轉換來檢查令牌是陣列還是物件。并反序列化為適當的型別。
class WorldBankApiResponseUnionConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(WorldBankApiResponseUnion) || t == typeof(WorldBankApiResponseUnion?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.StartObject:
var objectValue = serializer.Deserialize<WorldBankApiResponseGlobal>(reader);
return new WorldBankApiResponseUnion { WorldBankApiResponseGlobal = objectValue };
case JsonToken.StartArray:
var arrayValue = serializer.Deserialize<WorldBankApiResponse[]>(reader);
return new WorldBankApiResponseUnion { WorldBankApiResponse = arrayValue };
}
throw new Exception("Cannot unmarshal type WorldBankApiResponseUnion");
}
現場演示:https : //dotnetfiddle.net/3Rqnya
使用自動化工具:https : //app.quicktype.io/?l=csharp
uj5u.com熱心網友回復:
編輯:上面發布https://app.quicktype.io/?l=csharp以生成解決方案的評論看起來可以解決問題,盡管它會生成大量代碼。如果有一種簡單的方法可以洗掉標題,下面的將是更好的選擇。
我不確定如何洗掉“標題”,但也許您可以排除“標題”以保留核心資料,然后您會得到一些可能是 List 的東西
public class WorldBankApiResponse
{
public WorldBankApiIdValue Indicator { get; set; }
public WorldBankApiIdValue Country { get; set; }
public int Value { get; set; }
public string Date { get; set; }
public string Countryiso3code { get; set; }
}
uj5u.com熱心網友回復:
您可以使用System.Text.Json 中的 JsonDocument將頂級陣列中的第一項和第二項反序列化為單獨的物件,而無需使用 GetFromJsonAsync。
var json = @"
[
{ ""page_count"": 10 },
[
{ ""id"": 1 },
{ ""id"": 2 }
]
]
";
class Header
{
public int page_count { get; set; }
}
class Item
{
public int id { get; set; }
}
using var document = JsonDocument.Parse(json);
var header = document.RootElement[0].Deserialize<Header>();
var body = document.RootElement[1].Deserialize<List<Item>>();
如果您使用的是 Newtonsoft.Json,則等效項是 JArray(以及一般的JToken):
var jarray = JArray.Parse(json);
var header = jarray[0].ToObject<Header>();
var body = jarray[1].ToObject<List<Item>>();
uj5u.com熱心網友回復:
嘗試這個。它在 Visual Studio 中進行了測驗
var parsedArray=JArray.Parse(json);
// this is just an array part
List<WorldBankApiResponse> worldBankApiResponses =
JsonConvert.DeserializeObject<List<WorldBankApiResponse>>(parsedArray[1].ToString());
// this is just a header part
var wb =
JsonConvert.DeserializeObject<WorldBankApiResponseGlobal>(parsedArray[0].ToString());
//this is the whole object
var worldBankApiResponseGlobal= new WorldBankApiResponseGlobal{
Page=wb.Page,
Pages=wb.Pages,
PerPage=wb.PerPage,
Total=wb.Total,
Sourceid=wb.Sourceid,
Sourcename=wb.Sourcename,
Lastupdated=wb.Lastupdated,
WorldBankApiResponses= worldBankApiResponses
};
班級
public partial class WorldBankApiResponseGlobal
{
[JsonProperty("page")]
public long Page { get; set; }
[JsonProperty("pages")]
public long Pages { get; set; }
[JsonProperty("per_page")]
public long PerPage { get; set; }
[JsonProperty("total")]
public long Total { get; set; }
[JsonProperty("sourceid")]
public long Sourceid { get; set; }
[JsonProperty("sourcename")]
public string Sourcename { get; set; }
[JsonProperty("lastupdated")]
public DateTimeOffset Lastupdated { get; set; }
[JsonProperty("WorldBankApiResponses")]
public List<WorldBankApiResponse> WorldBankApiResponses { get; set; }
}
public partial class WorldBankApiResponse
{
[JsonProperty("indicator")]
public WorldBankApiIdValue Indicator { get; set; }
[JsonProperty("country")]
public WorldBankApiIdValue Country { get; set; }
[JsonProperty("countryiso3code")]
public string Countryiso3Code { get; set; }
[JsonProperty("date")]
public long Date { get; set; }
[JsonProperty("value")]
public double Value { get; set; }
[JsonProperty("unit")]
public string Unit { get; set; }
[JsonProperty("obs_status")]
public string ObsStatus { get; set; }
[JsonProperty("decimal")]
public long Decimal { get; set; }
}
public partial class WorldBankApiIdValue
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/364418.html
標籤:C# json asp.net核心 反序列化 http客户端
上一篇:將安全驗證碼存盤在Redis中
