【问题标题】:Serialise list of C# custom objects序列化 C# 自定义对象的列表
【发布时间】:2015-10-01 12:56:13
【问题描述】:

我从 API 接收到一个 JSON 字符串,该字符串的结构在应用程序中处理得不好。

我选择为这个 JSON 数据创建一个自定义序列化器(而不是为应用中接收和使用的数据创建两个不同的类)。

根据大量教程,我设法为单个对象组合了一个自定义序列化程序。但是,我需要处理这些对象的列表(这些奇怪的列表中会出现更多不同的数据,需要自定义处理)。

是否有一种内置方法可以设置我的自定义序列化程序以处理列表中的每个对象?还是我需要手动拆分 JSON 对象,并将其大块提供给自定义序列化器?

对于如何处理这种情况的任何其他建议表示赞赏。

用户类别:

[JsonConverter(typeof(UserSerializer))]
    public class User
    {
        public int id;
        public string displayName;
        public string email;
        public int total_points;
        public float total_values;
    }

反序列化器:

public override object ReadJson(JsonReader reader, Type objectType, 
            object existingValue, JsonSerializer serializer)
        {
            JObject jObjectRoot = JObject.Load(reader);
            var root = jObjectRoot.Properties().ToList();
            JObject jObjectData = JObject.Load(root[2].Value.CreateReader());
            var data = jObjectData.Properties().ToList();
            return new User { 
                id = (int)root[1].Value,
                displayName = (string)data[0].Value,
                email = (string)data[1].Value,
                total_points = (int)data[2].Value,
                total_values = (float)data[3].Value
            };
        }

更新:

还有将 json 字符串解析为单个用户对象的代码:

public static void ProcessJSON(string json)
{
    User user = JsonConvert.DeserializeObject<User>(json);
}

还有 JSON 本身:

[
  {
    "type": "users",
    "id": 1,
    "attr": {
      "display_name": "user2",
      "email": "user2@email.com",
      "total_points": 4,
      "total_values": 32.34
    },
    "relationships": {
      "points_received": {
        "links": {
          "self": "tipjar/users/1/relationships/points",
          "related": "tipjar/users/1/points"
        }
      },
      "points_given": {
        "links": {
          "self": "tipjar/users/1/relationships/awarded",
          "related": "tipjar/users/1/awarded"
        }
      }
    }
  }
]

谢谢

【问题讨论】:

  • 你看过使用 Newtonsoft JSON.NET 吗?
  • JSON 看起来如何?
  • @GlenThomas 是的,我正在使用 Newtonsoft JSON.NET

标签: c# json serialization json.net json-deserialization


【解决方案1】:

您可以在没有自定义转换器的情况下获取用户对象列表,如下所示:

var userList = JArray.Parse(json)
    .Select(t => new User()
    {
        id = int.Parse(t["id"].ToString()),
        displayName = t["attr"]["display_name"].ToString(),
        email = t["attr"]["email"].ToString(),
        total_points = int.Parse(t["attr"]["total_points"].ToString()),
        total_values = float.Parse(t["attr"]["total_values"].ToString()),
    }).ToList();

【讨论】:

  • 哈哈,这就像一个魅力,无需编写复杂的转换器。非常感谢:)
  • 作为一个小改进,Json.Net 支持将JValues 直接转换为它们对应的原始类型,因此您可以使用total_points = (int)t["attr"]["total_points"] 而不是使用ToString() 然后int.Parse()
【解决方案2】:
public static void ProcessJSON(string json)
{
    User u = new User();
    var test = JsonConvert.DeserializeObject(json);
    if (test.GetType() == typeof(User))
        u = (User)test;

}

不是 100% 说明序列化是如何工作的,但这似乎在我制作的测试应用上有效。

这可能有点傻。但是您可以测试返回的不同类型的对象...

【讨论】:

  • 对不起,这根本行不通。如果您没有在DeserializeObject 中指定类型,那么它将是某种JToken,而不是User。因此用户u 将始终具有默认值。即使您确实将User 指定为DeserializeObject 的类型参数,JSON 也不匹配OP 定义的User 类。您的回答根本没有显示如何处理这种不匹配,也没有显示如何处理用户列表。这就是 OP 在这里试图解决的问题的症结所在。
  • 然后回到绘图板。我会对此做更多的研究。谢谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多