47

当我可以调用第 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"
      }
   ]
}

如果我在“数据”成员周围使用自定义包装类并且该成员需要是 type ,我只能让序列化工作List<object>。如果它有它们作为List<TheUser>ArgumentExceptionJsonParser DesializeType方法中得到的类型。

我最初尝试在没有这样的包装类型的情况下进行序列化

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

但这只会给我一个空集合。当然,我必须能够将数组反序列化为强类型列表。

4

8 回答 8

34

在查看源代码之后,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

于 2011-05-13T10:11:51.603 回答
16

尝试

List<TheUser> friends = jsonSerializer.Deserialize<List<TheUser>>(response);
于 2011-05-12T19:00:18.130 回答
11

这对我有用,可以将 JSON 反序列化为对象数组:

List<TheUser> friends = JsonConvert.DeserializeObject<List<TheUser>>(response);
于 2013-01-18T19:30:05.373 回答
9

这个解决方案似乎对我有用,并且不必编写一堆带有“数据”的类。

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();
} 
于 2012-08-08T20:25:53.907 回答
8

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();
于 2014-03-19T09:30:24.077 回答
2

Pat,json 结构看起来对我在这里描述的一个问题非常熟悉- 我的答案是将 json 表示视为 Dictionary<TKey, TValue>,即使只有 1 个条目。

如果我是正确的,您的密钥是字符串类型,并且是 List<T> 的值,其中 T 表示类“TheUser”

高温高压

PS - 如果你想要更好的序列化性能检查使用Silverlight Serializer,你需要构建一个 WP7 版本,无耻插件 - 我写了一篇关于这个的博客文章

于 2011-05-13T10:25:20.963 回答
1

我喜欢这种方法,它对我来说很直观。

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());
    }
于 2020-04-14T05:44:37.610 回答
0

我怀疑问题是因为 json 表示一个以用户列表作为属性的对象。尝试反序列化为:

public class UsersResponse
{
    public List<User> Data { get; set; }
}
于 2011-05-13T09:56:58.120 回答