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

发布于 2024-11-06 23:34:48 字数 903 浏览 1 评论 0原文

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

我只能在以下情况下使序列化正常工作我在“data”成员周围使用自定义包装类,并且该成员需要为 List类型。如果它们的类型为 List,我会从 JsonParser DesializeType 方法得到 ArgumentException

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

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

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

When I can call the 3rd party api and get back a single class worth of data everything deserialises fine using this code

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

The problem comes when I try and deserialise JSON response content that is an array, such as

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

I can only get the serialization to work if I use a custom wrapping class around the "data" member and that member needs to be of type List<object>. If it have them as type List<TheUser> I get ArgumentException from the JsonParser DesializeType method.

I originally tried to serialise without a wrapping type like this

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

but that just returns me an empty collection. Surely I must be able to have the array deserialize to a strongly typed list.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

ヅ她的身影、若隐若现 2024-11-13 23:34:48

查看源代码后,适用于 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();

and with:

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

Afer looking at the source, for WP7 Hammock doesn't actually use Json.Net for JSON parsing. Instead it uses it's own parser which doesn't cope with custom types very well.

If using Json.Net directly it is possible to deserialize to a strongly typed collection inside a wrapper object.

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

and with:

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

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

Having to create the extra object with the data property is annoying but that's a consequence of the way the JSON formatted object is constructed.

Documentation: Serializing and Deserializing JSON

你的心境我的脸 2024-11-13 23:34:48

尝试

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

try

List<TheUser> friends = jsonSerializer.Deserialize<List<TheUser>>(response);
飘过的浮云 2024-11-13 23:34:48

这对我来说很有效,可以将 JSON 反序列化为对象数组:

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

This worked for me for deserializing JSON into an array of objects:

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

This solution seems to work for me and gets around having to code a bunch of classes with "Data" in them.

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

I should have included this to begin with, here is an example method using the above:

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

    return userList.Data.ToList();
} 
殊姿 2024-11-13 23:34:48

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

Json.NET - Documentation

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

Interpretation for the author

var o = JObject.Parse(response);
var a = o.SelectToken("data").Select(jt => jt.ToObject<TheUser>()).ToList();
层林尽染 2024-11-13 23:34:48

JSON 结构看起来与我描述的问题非常熟悉 here - 答案是将 JSON 表示视为 Dictionary,即使只有 1 个 入口。

如果我是正确的,您的键是字符串类型,并且是 List 的值,其中 T 代表类 TheUser

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

The JSON structure looks very familiar to a problem I described here - The answer there was to treat the JSON representation as a Dictionary<TKey, TValue>, even though there was only 1 entry.

If I am correct your key is of type string and the value of a List<T> where T represents the class TheUser.

If you want better serialisation performance check out using Silverlight Serializer, you'll need to build a WP7 version. Shameless plug - I wrote a blog post about this.

猫腻 2024-11-13 23:34:48

我喜欢这种方法,它对我来说是视觉化的。

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

I like this approach, it is visual for me.

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());
    }
慕巷 2024-11-13 23:34:48

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

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

I suspect the problem is because the json represents an object with the list of users as a property. Try deserializing to something like:

public class UsersResponse
{
    public List<User> Data { get; set; }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文