无法在c#中获得JSON序列化

本文关键字:JSON 序列化 | 更新日期: 2023-09-27 18:07:04

我之前已经能让它工作了,但不知什么原因,我不能让它在这个特殊的情况下工作,这让我发疯。

这是我得到的JSON(使用Toggl API):

{
  "total_grand": 1112836000,
  "total_billable": 598417000,
  "total_currencies": [
    {
      "currency": "USD",
      "amount": 1154.11
    }
  ],
  "total_count": 2,
  "per_page": 50,
  "data": [
    {
      "id": 445687319,
      "pid": 21026846,
      "tid": 10185176,
      "uid": 2317636,
      "description": "Just doin' it...",
      "start": "2016-09-14T10:17:42-04:00",
      "end": "2016-09-14T10:19:13-04:00",
      "updated": "2016-09-14T10:12:08-04:00",
      "dur": 91000,
      "user": "UserName",
      "use_stop": true,
      "client": null,
      "project": "My Project",
      "project_color": "12",
      "project_hex_color": "#094558",
      "task": "New Task",
      "billable": 10.11,
      "is_billable": true,
      "cur": "USD",
      "tags": []
    },
    {
      "id": 445687306,
      "pid": null,
      "tid": null,
      "uid": 2317636,
      "description": "",
      "start": "2016-09-14T10:17:39-04:00",
      "end": "2016-09-14T10:17:39-04:00",
      "updated": "2016-09-14T10:10:34-04:00",
      "dur": 0,
      "user": "UserName",
      "use_stop": true,
      "client": null,
      "project": null,
      "project_color": "0",
      "project_hex_color": null,
      "task": null,
      "billable": 0,
      "is_billable": false,
      "cur": "USD",
      "tags": []
    }
  ]
}

这是我用来序列化的类。我把上面的JSON粘贴到Visual Studio 2015作为一个类,但它使Rootobject中的total_currenciesdata字段变成数组(即- public Datum[] data { get; set; },我相信我应该改成List<T>,如下所示)。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace TogglApp1
{
    public class Rootobject
    {
        public int total_grand { get; set; }
        public int total_billable { get; set; }
        // public Total_Currencies[] total_currencieis { get; set; }
        public List<Total_Currencies> total_currencies { get; set; }
        public int total_count { get; set; }
        public int per_page { get; set; }
        // public Datum[] data { get; set; }
        public List<Datum> data { get; set; }
    }
    public class Total_Currencies
    {
        public string currency { get; set; }
        public float amount { get; set; }
    }
    public class Datum
    {
        public int id { get; set; }
        public int? pid { get; set; }
        public int? tid { get; set; }
        public int uid { get; set; }
        public string description { get; set; }
        public DateTime start { get; set; }
        public DateTime end { get; set; }
        public DateTime updated { get; set; }
        public int dur { get; set; }
        public string user { get; set; }
        public bool use_stop { get; set; }
        public object client { get; set; }
        public string project { get; set; }
        public string project_color { get; set; }
        public string project_hex_color { get; set; }
        public string task { get; set; }
        public float billable { get; set; }
        public bool is_billable { get; set; }
        public string cur { get; set; }
        public string[] tags { get; set; }
    }
}

这里是我(试图)使用的c#代码来匹配这些…

using System;
using RestSharp;
using System.Net;
using System.Runtime.Serialization.Json;
namespace TogglApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // ENTER THE TEST TYPE
            // 1 = ENJOY SUCCESS WITH CONTENT FROM TOGGL API
            // 2 = THIS CODE TOYS WITH YOUR LIFE UNTIL THERE IS NONE LEFT
            // 3 = THIS CODE IS A GRAVEYARD OF BURIED HOPES AND DREAMS
            //
            int intTestType = 3;
            string strAuthCode = "[YOUR-API-KEY-GOES-HERE]";
            var client = new RestClient("https://www.toggl.com");
            var request = new RestRequest("/api/v8/workspaces");
            request.AddHeader("Authorization", $"Basic {strAuthCode}");
            request.AddHeader("Content-type", "application/json");
            switch (intTestType)
            {
                case 1:
                    {
                        Console.Write("Getting API Data via RestSharp...");
                        IRestResponse response = client.Execute(request);
                        var content = response.Content;
                        // THIS WORKS - I AM GETTING THE CORRECT CONTENT
                        Console.WriteLine(content);
                        Console.ReadLine();
                        break;
                    }
                case 2:
                    {
                        Console.Write("Serializing API Data using RestSharp...");
                        var response1 = client.Execute<Rootobject>(request);
                        // THIS DOES NOT WORK - `data1` IS ALWAYS NULL
                        var data1 = response1.Data;
                        Console.Write("DONE! Check it!");
                        Console.ReadLine();
                        break;
                    }
                case 3:
                    {
                        Console.Write("Serializing API Data using MakeRequest...");
                        string[] strAuth = new string[] { "Authorization", $"Basic {strAuthCode}" };
                        string[][] myHeaders = new string[][] { strAuth };
                        var response2 = MakeRequest<Rootobject>("https://www.toggl.com/api/v8/workspaces", myHeaders);
                        // THIS DOES NOT WORK - `data2` IS ALWAYS NULL
                        var data2 = response2.data;
                        Console.Write("DONE! Check it!");
                        Console.ReadLine();
                        break;
                    }
                default:
                    {
                        break;
                    }
            }
        }
        public static T MakeRequest<T>(string strUrl, string[][] strHeaders, string strRequestMethod = "GET") where T : class
        {
            // NOTE PARAMETERS ARE PASSED IN QUERYSTRING INSIDE URL
            try
            {
                HttpWebRequest request = WebRequest.Create(strUrl) as HttpWebRequest;
                request.Method = strRequestMethod;
                request.ContentType = "application/json";
                foreach (string[] strHeader in strHeaders)
                {
                    request.Headers.Add(strHeader[0], strHeader[1]);
                }
                using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
                {
                    if (response.StatusCode != HttpStatusCode.OK)
                        throw new Exception(String.Format(
                        "Server error (HTTP {0}: {1}).",
                        response.StatusCode,
                        response.StatusDescription));
                    DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(T));
                    object objResponse = jsonSerializer.ReadObject(response.GetResponseStream());
                    var jsonResponse = (T)objResponse;
                    response.Close();
                    return jsonResponse;
                }
            }
            catch (Exception ex)
            {
                return default(T);
            }
        }
    }
}

好吧,所以这两个方法都不起作用,我几乎可以肯定它与序列化类有关,但我没有得到任何错误,如ERROR: HEY YOUR CLASS DOESN'T MATCH UP WITH THE JSON I GOT FROM THE SERVER…相反,它根本不起作用,要么用零填充值,要么用空填充值。

希望能得到一些帮助…什么好主意吗?

根据下面的建议,我将JSON粘贴到json2sharp中,得到了下面的响应,与我的基本相同。我还更新了在序列化器类中使用这个版本,并得到相同的结果。

public class TotalCurrency
{
    public string currency { get; set; }
    public double amount { get; set; }
}
public class Datum
{
    public int id { get; set; }
    public int? pid { get; set; }
    public int? tid { get; set; }
    public int uid { get; set; }
    public string description { get; set; }
    public string start { get; set; }
    public string end { get; set; }
    public string updated { get; set; }
    public int dur { get; set; }
    public string user { get; set; }
    public bool use_stop { get; set; }
    public object client { get; set; }
    public string project { get; set; }
    public string project_color { get; set; }
    public string project_hex_color { get; set; }
    public string task { get; set; }
    public double billable { get; set; }
    public bool is_billable { get; set; }
    public string cur { get; set; }
    public List<object> tags { get; set; }
}
public class RootObject
{
    public int total_grand { get; set; }
    public int total_billable { get; set; }
    public List<TotalCurrency> total_currencies { get; set; }
    public int total_count { get; set; }
    public int per_page { get; set; }
    public List<Datum> data { get; set; }
}

无法在c#中获得JSON序列化

我一直使用JsonTextReader处理传入流,没有问题…(无错误处理)

public async Task<API_Json.RootObject> walMart_Lookup(string url)
    {
        lookupIsWorking = true;
        HttpClientHandler handler = new HttpClientHandler()
        {
            AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
        };
        using (HttpClient http = new HttpClient(handler))
        {
            http.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));
            http.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
            url = String.Format(url);
            using (var response = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
            {
                Console.WriteLine(response);
                var serializer = new JsonSerializer();
                using (StreamReader sr = new StreamReader(await response.Content.ReadAsStreamAsync()))
                {
                    using (var jsonTextReader = new JsonTextReader(sr))
                    {
                        var root = serializer.Deserialize<API_Json.RootObject>(jsonTextReader);
                       lookupIsWorking = false;
                        return root;
                    }
                }
            }
        }

    }

你还需要添加属性到你的Json类:

 [DataContract]
 public class Rootobject
{
    [DataMember]
    public int total_grand { get; set; }
    [DataMember]
    public int total_billable { get; set; }
    [DataMember]
    public List<Total_Currencies> total_currencies { get; set; }
    [DataMember]
    public int total_count { get; set; }
    [DataMember]
    public int per_page { get; set; }
    [DataMember]
    public List<Datum> data { get; set; }
}
[DataContract]
public class Total_Currencies
{
    [DataMember]
    public string currency { get; set; }
    [DataMember]
    public float amount { get; set; }
}
[DataContract]
public class Datum
{
    [DataMember]
    public int id { get; set; }
    [DataMember]
    public int? pid { get; set; }
    [DataMember]
    public int? tid { get; set; }
    [DataMember]
    public int uid { get; set; }
    [DataMember]
    public string description { get; set; }
    [DataMember]
    public DateTime start { get; set; }
    [DataMember]
    public DateTime end { get; set; }
    [DataMember]
    public DateTime updated { get; set; }
    [DataMember]
    public int dur { get; set; }
    [DataMember]
    public string user { get; set; } 
    [DataMember]
    public bool use_stop { get; set; }
    [DataMember]
    public object client { get; set; }
    [DataMember]
    public string project { get; set; }
    [DataMember]
    public string project_color { get; set; }
    [DataMember]
    public string project_hex_color { get; set; }
    [DataMember]
    public string task { get; set; }
    [DataMember]
    public float billable { get; set; }
    [DataMember]
    public bool is_billable { get; set; }
    [DataMember]
    public string cur { get; set; }
    [DataMember]
    public string[] tags { get; set; }
}