从 Zendesk 获取门票并插入 SQL

Get tickets from Zendesk and insert to SQL

我正在尝试通过 Zendesk v2 API 从控制台应用程序获取 Zendesk 票证,然后插入到 sql 数据库,但出现错误。

Newtonsoft.Json.JsonSerializationException:无法将当前 JSON 对象(例如 {"name":"value"})反序列化为类型 'System.Collections.Generic.List`1[ZenTrack.Class1+Ticket]',因为该类型需要 JSON数组(例如 [1,2,3])以正确反序列化。

错误 crystal 对于理解这一点的人来说是显而易见的...我不是那些人中的一员! 我哪里做错了?

所以我的代码是这样的:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using static ZenGet.Class1;

namespace ZenGet
{
    class Program
    {
        static void Main(string[] args)
        {
            HttpClient client = new HttpClient();
            client.BaseAddress = new Uri("https://myportal.zendesk.com/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Add("Authorization", "Basic xxxxxxxxxxxxxxxxxxxxxx");
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            string path = "api/v2/tickets.json?page=1";

            FileStream fs = new FileStream("c:\Test.txt", FileMode.Create);
            StreamWriter sw = new StreamWriter(fs);

            try
            {
                HttpResponseMessage response = client.GetAsync(path).Result;

                //Http Status code 200
                if (response.IsSuccessStatusCode)
                {
                    //Read response content result into string variable
                    string JSON = response.Content.ReadAsStringAsync().Result;

                    //Deserialize the string(JSON) object
                    var RootObjects = JsonConvert.DeserializeObject<List<Ticket>>(JSON);

                    foreach (var rootObject in RootObjects)
                    {
                        Console.WriteLine(rootObject.id + "-" + rootObject.subject + "-" + rootObject.description + "-" + rootObject.status);

                      // The SQL insert goes here.

                    }

                }
            }
            catch (Exception exception)
            {
                Console.SetOut(sw);
                Console.WriteLine($"Exception: {exception}");

            }
            sw.Close();


        }

    }
}

class 看起来像这样:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZendeskApi_v2.Models.Tickets;

namespace ZenGet
{
    class Class1
    {
        public class From
        {
        }

        public class To
        {
        }

        public class Source
        {
            [JsonProperty("from")]
            public From from { get; set; }
            [JsonProperty("to")]
            public To to { get; set; }
            [JsonProperty("rel")]
            public object rel { get; set; }
        }

        public class Via
        {
            [JsonProperty("channel")]
            public string channel { get; set; }
            [JsonProperty("source")]
            public Source source { get; set; }
        }

        public class Ticket
        {
            [JsonProperty("url")]
            public string url { get; set; }
            [JsonProperty("id")]
            public int id { get; set; }
            [JsonProperty("external_id")]
            public object external_id { get; set; }
            [JsonProperty("via")]
            public Via via { get; set; }
            [JsonProperty("created_at")]
            public DateTime created_at { get; set; }
            [JsonProperty("updated_at")]
            public DateTime updated_at { get; set; }
            [JsonProperty("type")]
            public string type { get; set; }
            [JsonProperty("subject")]
            public string subject { get; set; }
            [JsonProperty("raw_subject")]
            public string raw_subject { get; set; }
            [JsonProperty("description")]
            public string description { get; set; }
            [JsonProperty("priority")]
            public string priority { get; set; }
            [JsonProperty("status")]
            public string status { get; set; }
            [JsonProperty("recipient")]
            public object recipient { get; set; }
            [JsonProperty("requester_id")]
            public object requester_id { get; set; }
            [JsonProperty("submitter_id")]
            public object submitter_id { get; set; }
            [JsonProperty("assignee_id")]
            public object assignee_id { get; set; }
            [JsonProperty("organization_id")]
            public object organization_id { get; set; }
            [JsonProperty("group_id")]
            public object group_id { get; set; }
            [JsonProperty("collaborator_ids")]
            public List<object> collaborator_ids { get; set; }
            [JsonProperty("follower_ids")]
            public List<object> follower_ids { get; set; }
            [JsonProperty("email_cc_ids")]
            public List<object> email_cc_ids { get; set; }
            [JsonProperty("forum_topic_id")]
            public object forum_topic_id { get; set; }
            [JsonProperty("problem_id")]
            public object problem_id { get; set; }
            [JsonProperty("has_incidents")]
            public bool has_incidents { get; set; }
            [JsonProperty("is_public")]
            public bool is_public { get; set; }
            [JsonProperty("due_at")]
            public object due_at { get; set; }
            [JsonProperty("tags")]
            public List<string> tags { get; set; }
            [JsonProperty("custom_fields")]
            public List<object> custom_fields { get; set; }
            [JsonProperty("satisfaction_rating")]
            public object satisfaction_rating { get; set; }
            [JsonProperty("sharing_agreement_ids")]
            public List<object> sharing_agreement_ids { get; set; }
            [JsonProperty("fields")]
            public List<object> fields { get; set; }
            [JsonProperty("followup_ids")]
            public List<object> followup_ids { get; set; }
            [JsonProperty("brand_id")]
            public object brand_id { get; set; }
            [JsonProperty("allow_channelback")]
            public bool allow_channelback { get; set; }
            [JsonProperty("allow_attachments")]
            public bool allow_attachments { get; set; }
        }

        public class Root
        {
            [JsonProperty("tickets")]
            public Ticket[] Tickets { get; set; }
        }


    }
}

json 响应:

tickets: [
  {
    "url": "https://myportal.zendesk.com/api/v2/tickets/2.json",
    "id": 2,
    "external_id": null,
    "via": {
      "channel": "sample_ticket",
      "source": {
        "from": {},
        "to": {},
        "rel": null
      }
    },
    "created_at": "2020-12-09T07:20:17Z",
    "updated_at": "2020-12-13T08:01:20Z",
    "type": "incident",
    "subject": "Jag behöver hjälp",
    "raw_subject": "Jag behöver hjälp",
    "description": "Hej,\nNågot dramatiskt har inträffat och jag behöver verkligen din hjälp.\nTack på förhand,\nKund\n",
    "priority": "normal",
    "status": "closed",
    "recipient": null,
    "requester_id": 376279908200,
    "submitter_id": 376279896900,
    "assignee_id": 376279896900,
    "organization_id": null,
    "group_id": 360005730200,
    "collaborator_ids": [],
    "follower_ids": [],
    "email_cc_ids": [],
    "forum_topic_id": null,
    "problem_id": null,
    "has_incidents": false,
    "is_public": true,
    "due_at": null,
    "tags": [
      "support-exempel",
      "zendesk"
    ],
    "custom_fields": [],
    "satisfaction_rating": null,
    "sharing_agreement_ids": [],
    "fields": [],
    "followup_ids": [],
    "brand_id": 360002066200,
    "allow_channelback": false,
    "allow_attachments": true
  }
]
next_page: 
next_page: 
previous_page: 
previous_page: 
count: 3
count: 3

我试过更改行: var RootObjects = JsonConvert.DeserializeObject<列表>(JSON); 到 动态而不是 var 并 动态 RootObjects = JsonConvert.DeserializeObject(JSON);

我在 class 中从

更改了
        public class Source
        {
            public From from { get; set; }
            public To to { get; set; }
            public object rel { get; set; }

        public class Source
        {
            [JsonProperty("from")]   <-- added this 
            public From from { get; set; }
            [JsonProperty("to")]     <-- added this 
            public To to { get; set; }
            [JsonProperty("rel")]    <-- added this 
            public object rel { get; set; }

您尝试将 json 对象反序列化为工单列表。但是您必须将其反序列化为包含票证列表的根对象:

变化:

 var RootObjects = JsonConvert.DeserializeObject<List<Ticket>>(JSON);

收件人:

var RootObjects = JsonConvert.DeserializeObject<Root>(JSON);