无法在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_currencies
和data
字段变成数组(即- 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; }
}
我一直使用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; }
}