2016-09-14 101 views
0

我已經能夠得到這個工作之前,但無論什麼原因,我無法得到它在這種特殊情況下工作,這是讓我瘋狂。無法獲得JSON序列化在C#

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

{ 
    "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年爲一類,但它使在Rootobjecttotal_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 ... inst它只是簡單的不工作,並用零或空值填充值。

想在這裏得到一些幫助...任何想法?

UPDATE

每下面的建議,我粘貼到JSON和json2csharp得到了下面的反應,基本上像我一樣。我還更新了在序列化程序類中使用此版本並獲得相同的結果。

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

嘗試粘貼您的JSON到這個網站,看看你得到不同的東西:http://json2csharp.com/# –

+0

@ShannonHolsinger - 剛剛試了一下......同一樣的。 – gotmike

+0

使用JSON.NET進行測試,並且工作完美 – Plutonix

回答

0

與輸入數據流打交道時,我一直使用的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; 

        } 
       } 

      } 

     } 


    } 

您還需要添加propoer屬性您的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; } 
} 
+0

我昨天在討論中遺漏了一些東西 - 請注意我編輯的答案... –

+0

我注意到你添加了' [DataContract]'和'[DataMember]' - 我已經嘗試了這兩種方法,這兩種方法似乎都行得通(不是在這種情況下,而是在其他方面) - 什麼時候需要,什麼時候不需要? – gotmike

+0

老實說,我不知道 - 只知道我不得不添加它們,當我做它時,它從null/0變成了好的反序列化... –