将JSON数组反序列化为强类型.NET对象

时间:2011-05-12 14:20:27

标签: c# windows-phone-7 json.net hammock

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

如果我在“data”成员周围使用自定义包装类并且该成员需要是List<object>类型,我只能使序列化工作。如果它们的类型为List<TheUser>,我会从ArgumentException方法获得JsonParser DesializeType

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

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

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

8 个答案:

答案 0 :(得分:29)

看看the source,对于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格式对象的方式的结果。

文档: Serializing and Deserializing JSON

答案 1 :(得分:11)

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

答案 2 :(得分:7)

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

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();
} 

答案 3 :(得分:7)

这有助于我将JSON反序列化为一个对象数组:

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

答案 4 :(得分:6)

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();

答案 5 :(得分:2)

Pat,json结构对于我描述的here问题看起来非常熟悉 - 我的答案是将json表示视为字典&lt; TKey,TValue&gt;,即使只有1个条目。< / p>

如果我是正确的,你的密钥是字符串类型,并且List&lt; T&gt;的值是其中T代表“TheUser”类

HTH

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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

我喜欢这种方法,对我来说是直观的。

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());
    }