簡體   English   中英

將 JSON 數組反序列化為強類型 .NET 對象

[英]Deserializing JSON array into strongly typed .NET object

當我可以調用第 3 方 api 並取回單個類的數據時,使用此代碼可以很好地反序列化

TheUser me = jsonSerializer.Deserialize(response, typeof(TheUser)) as TheUser

當我嘗試反序列化作為數組的 JSON 響應內容時,問題就出現了,例如

{
   "data": [
      {
         "name": "A Jones",
         "id": "500015763"
      },
      {
         "name": "B Smith",
         "id": "504986213"
      },
      {
         "name": "C Brown",
         "id": "509034361"
      }
   ]
}

如果我在“數據”成員周圍使用自定義包裝類,並且該成員需要是List<object>類型,則我只能使序列化工作。 如果將它們作為List<TheUser>類型,我會從JsonParser DesializeType方法中得到ArgumentException

我最初嘗試在沒有這樣的包裝類型的情況下進行序列化

List<TheUser> freinds = jsonSerializer.Deserialize(response, typeof(List<TheUser>)) as List<TheUser>;

但這只會給我返回一個空集合。 當然,我必須能夠將數組反序列化為強類型列表。

Afer 查看源代碼,對於 WP7 Hammock 實際上並不使用 Json.Net 進行 JSON 解析。 相反,它使用自己的解析器,不能很好地處理自定義類型。

如果直接使用Json.Net ,則可以反序列化為包裝對象內的強類型集合。

var response = @"
    {
        ""data"": [
            {
                ""name"": ""A Jones"",
                ""id"": ""500015763""
            },
            {
                ""name"": ""B Smith"",
                ""id"": ""504986213""
            },
            {
                ""name"": ""C Brown"",
                ""id"": ""509034361""
            }
        ]
    }
";

var des = (MyClass)Newtonsoft.Json.JsonConvert.DeserializeObject(response, typeof(MyClass));

return des.data.Count.ToString();

與:

public class MyClass
{
    public List<User> data { get; set; }
}

public class User
{
    public string name { get; set; }
    public string id { get; set; }
}

必須使用 data 屬性創建額外的對象很煩人,但這是構造 JSON 格式對象的方式的結果。

文檔: 序列化和反序列化 JSON

嘗試

List<TheUser> friends = jsonSerializer.Deserialize<List<TheUser>>(response);

這對我有用,可以將 JSON 反序列化為對象數組:

List<TheUser> friends = JsonConvert.DeserializeObject<List<TheUser>>(response);

這個解決方案似乎對我有用,並且不必編寫一堆帶有“數據”的類。

public interface IDataResponse<T> where T : class
{
    List<T> Data { get; set; }
}

public class DataResponse<T> : IDataResponse<T> where T : class
{
   [JsonProperty("data")]
   public List<T> Data { get; set; }
}

我應該首先包含它,這是使用上述方法的示例方法:

public List<TheUser> GetUser()
{
    var results = GetUserJson();
    var userList = JsonConvert.DeserializeObject<DataResponse<TheUser>>(results.ToString());

    return userList.Data.ToList();
} 

Json.NET - 文檔

http://james.newtonking.com/json/help/index.html?topic=html/SelectToken.htm

對作者的解釋

var o = JObject.Parse(response);
var a = o.SelectToken("data").Select(jt => jt.ToObject<TheUser>()).ToList();

Pat,json 結構對於我在這里描述的問題非常熟悉 - 我的答案是將 json 表示視為 Dictionary<TKey, TValue>,即使只有 1 個條目。

如果我是正確的,您的密鑰是字符串類型,並且是 List<T> 的值,其中 T 代表類“TheUser”

HTH

PS - 如果你想要更好的序列化性能檢查使用Silverlight Serializer ,你需要構建一個 WP7 版本,無恥插件 - 我寫了一篇關於這個的博客文章

我懷疑問題是因為 json 表示一個對象,其中包含用戶列表作為屬性。 嘗試反序列化為:

public class UsersResponse
{
    public List<User> Data { get; set; }
}

我喜歡這種方法,它對我來說很直觀。

using (var webClient = new WebClient())
    {
          var response = webClient.DownloadString(url);
          JObject result = JObject.Parse(response);
          var users = result.SelectToken("data");   
          List<User> userList = JsonConvert.DeserializeObject<List<User>>(users.ToString());
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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