如何从 HubSpot 反序列化 JSON

How to deserialise JSON from HubSpot

我在反序列化从 HubSpot ContactList API 收到的 JSON 时遇到问题。

我正在使用 Restsharp 和 NewtonSoft,我在理解如何正确定义所需的 类 以便反序列化下面的 JSON 字符串方面遇到了真正的困难:

  "contacts": [
    {
      "vid": 2251,
      "portal-id": 5532227,
      "is-contact": true,
      "profile-url": "https://app.hubspot.com/contacts/5532227/contact/2251",
      "properties": {
        "firstname": {
          "value": "Carl"
        },
        "lastmodifieddate": {
          "value": "1554898386040"
        },
        "company": {
          "value": "Cygnus Project"
        },
        "lastname": {
          "value": "Swann"
        }
      },
      "form-submissions": [],
      "identity-profiles": [
        {
          "vid": 2251,
          "saved-at-timestamp": 1553635648634,
          "deleted-changed-timestamp": 0,
          "identities": [
            {
              "type": "EMAIL",
              "value": "cswann@cygnus.co.uk",
              "timestamp": 1553635648591,
              "is-primary": true
            },
            {
              "type": "LEAD_GUID",
              "value": "e2345",
              "timestamp": 1553635648630
            }
          ]
        }
      ],
      "merge-audits": []
    },
    {
      "vid": 2301,
      "portal-id": 5532227,
      "is-contact": true,
      "profile-url": "https://app.hubspot.com/contacts/5532227/contact/2301",
      "properties": {
        "firstname": {
          "value": "Carlos"
        },
        "lastmodifieddate": {
          "value": "1554886333954"
        },
        "company": {
          "value": "Khaos Control"
        },
        "lastname": {
          "value": "Swannington"
        }
      },
      "identity-profiles": [
        {
          "vid": 2301,
          "saved-at-timestamp": 1553635648733,
          "deleted-changed-timestamp": 0,
          "identities": [
            {
              "type": "EMAIL",
              "value": "cswann@khaoscontrol.com",
              "timestamp": 1553635648578,
              "is-primary": true
            },
            {
              "type": "LEAD_GUID",
              "value": "c7f403ba",
              "timestamp": 1553635648729
            }
          ]
        }
      ],
      "merge-audits": []
    }
  ],
  "has-more": false,
  "vid-offset": 2401
}

如果我只是请求视频,我会正确地得到 2 个视频。当我尝试做这些属性时,我失败了。

请帮忙

让我们将 Json 减少到最小值以重现您的错误:

{
    "vid": 2301,
    "portal-id": 5532227,
    "is-contact": true,
    "profile-url": "https://app.hubspot.com/contacts/5532227/contact/2301",
    "properties": {
        "firstname": {
            "value": "Carlos"
        },
        "lastmodifieddate": {
            "value": "1554886333954"
        },
        "company": {
            "value": "Khaos Control"
        },
        "lastname": {
            "value": "Swannington"
        }
    }
}

和适当的classContactListAPI_Result

public partial class ContactListAPI_Result
{
    [JsonProperty("vid")]
    public long Vid { get; set; }

    [JsonProperty("portal-id")]
    public long PortalId { get; set; }

    [JsonProperty("is-contact")]
    public bool IsContact { get; set; }

    [JsonProperty("profile-url")]
    public Uri ProfileUrl { get; set; }

    [JsonProperty("properties")]
    public Dictionary<string, Dictionary<string, string>> Properties { get; set; }
}

public partial class ContactListAPI_Result
{
    public static ContactListAPI_Result FromJson(string json) 
        => JsonConvert.DeserializeObject<ContactListAPI_Result>(json);
    //public static ContactListAPI_Result FromJson(string json) 
    //  => JsonConvert.DeserializeObject<ContactListAPI_Result>(json, Converter.Settings);
}

public static void toto()
{
    string input = @"    {
    ""vid"": 2301,
    ""portal-id"": 5532227,
    ""is-contact"": true,
    ""profile-url"": ""https://app.hubspot.com/contacts/5532227/contact/2301"",
    ""properties"": {
        ""firstname"": {
            ""value"": ""Carlos""
        },
        ""lastmodifieddate"": {
            ""value"": ""1554886333954""
        },
        ""company"": {
            ""value"": ""Khaos Control""
        },
        ""lastname"": {
            ""value"": ""Swannington""
        }
    }
}";

    var foo = ContactListAPI_Result.FromJson(input);
}

但是一个属性的值会在子字典中挖洞,我们可以将对象投射到一个更有用的字典中:

public partial class ItemDTO
{
    public long Vid { get; set; }
    public long PortalId { get; set; }
    public bool IsContact { get; set; }
    public Uri ProfileUrl { get; set; }
    public Dictionary<string, string> Properties { get; set; }
}

将投影添加到 Class:

public ItemDTO ToDTO()
{
    return new ItemDTO
    {
        Vid = Vid,
        PortalId = PortalId,
        IsContact = IsContact,
        ProfileUrl = ProfileUrl,
        Properties = 
            Properties.ToDictionary(
                p => p.Key, 
                p => p.Value["value"]
            )
    };
}

用法:

var result = foo.ToDTO();

Live Demo

为大 key/value 对 json 创建和管理 class 结构是一项乏味的任务

所以一种方法是使用 JToken

您可以简单地将您的 JSON 解析为 JToken 并通过 querying 解析的对象,您将轻松读取您想要的数据,而无需为您的创建 class 结构json

从你的 post 看来你需要从你的 json 中检索 vidproperties 所以试试下面的代码,

string json = "Your json here";

JToken jToken = JToken.Parse(json);

var result = jToken["contacts"].ToObject<JArray>()
    .Select(x => new
    {
        vid = Convert.ToInt32(x["vid"]),
        properties = x["properties"].ToObject<Dictionary<string, JToken>>()
                                    .Select(y => new
                                    {
                                       Key = y.Key,
                                       Value = y.Value["value"].ToString()
                                    }).ToList()
    }).ToList();


//-----------Print the result to console------------

foreach (var item in result)
{
    Console.WriteLine(item.vid);

    foreach (var prop in item.properties)
    {
        Console.WriteLine(prop.Key + " - " + prop.Value);
    }

    Console.WriteLine();
}

输出: