无法将 Asana 用户数据反序列化为 C# class
Can't deserialize Asana User data into C# class
我正在尝试反序列化我从 Asana API 中的 users/me 调用中获取的数据,如下所示,但该对象为 jsonResponse var 中的所有属性返回 null .数据就在那里——如果我以纯文本形式阅读它,我就能看到它。我也尝试使用 [JsonProperty("id")] 属性而不是 [DataMember] 来使用 JsonSerializer 而不是 DataContractJsonSerializer,但我得到一个例外:"Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Data2'."
我做错了什么?
注意:我一直在使用 Xamasoft JSON Class Generator 创建 classes;请参阅 GetUser 方法下方的 class。
public AsanaObjects.Data2 GetUser()
{
AsanaObjects.Data2 result = null;
string url = "https://app.asana.com/api/1.0/users/me";
try
{
var uri = new Uri(url);
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CertificateCheck);
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
//Must use Tls12 or else exception: "The underlying connection was closed: An unexpected error occurred on a send." InnerException = {"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."}
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Timeout = 10000;
webRequest.Method = "GET"; webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Accept = "application/json";
//webRequest.UseDefaultCredentials = true; //doesn't seem to make a difference
webRequest.Headers.Add("Authorization", "Bearer " + AsanaBroker.Properties.Settings.Default.AccessToken);
using (var response = webRequest.GetResponse())
{
//using (var responseStream = ((HttpWebResponse)response).GetResponseStream())
//{
// if (responseStream != null)
// {
// var reader = new System.IO.StreamReader(responseStream);
// string readerText = reader.ReadToEnd();
// //Example return data: {"data":{"id":12343281337970,"name":"Eric Legault","email":"eric@foo.com","photo":null,"workspaces":[{"id":1234250096894,"name":"foo"},{"id":123446170860,"name":"Personal Projects"},{"id":12345000597911,"name":"foo2"}]}}
// }
//}
using (var responseStream = ((HttpWebResponse)response).GetResponseStream())
{
if (responseStream != null)
{
try
{
AsanaObjects.Data2 jsonResponse = null;
var jsonSerializer = new DataContractJsonSerializer(typeof(AsanaObjects.Data2));
jsonResponse = jsonSerializer.ReadObject(responseStream) as AsanaObjects.Data2;
if (jsonResponse != null)
{
result = jsonResponse;
}
}
catch (Exception ex)
{
Log.Error(ex);
}
}
}
}
}
catch (Exception ex)
{
}
return result;
}
这是我正在尝试反序列化的 class(很抱歉最初未格式化的部分 - 不确定如何修复):
public 部分 class AsanaObjects
{
[数据合约]
public class 工作区
{
[数据成员]
public 对象 ID { 获取;放; }
[DataMember]
public string name { get; set; }
}
}
public partial class AsanaObjects
{
[DataContract]
public class Data2
{
[DataMember]
public long id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string email { get; set; }
[DataMember]
public object photo { get; set; }
[DataMember]
public Workspace[] workspaces { get; set; }
}
}
public partial class AsanaObjects
{
[DataMember]
public Data2[] data { get; set; }
}
data
不是数组。在您的示例中,它是单个对象。
- 您想在根
AsanaObjects
class 处进行反序列化,而不是在 data
class 下一级。
- 我还不得不在根
AsanaObjects
class 上抛出一个 [DataContract]
以下有效并返回一个完整的对象:
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
const string Json = @"{""data"":{""id"":12343281337970,""name"":""Eric Legault"",""email"":""eric@foo.com"",""photo"":null,""workspaces"":[{""id"":1234250096894,""name"":""foo""},{""id"":123446170860,""name"":""Personal Projects""},{""id"":12345000597911,""name"":""foo2""}]}}";
static void Main(string[] args)
{
var theReturn = DeserializeJson(Json);
}
private static AsanaObjects DeserializeJson(string json) {
var jsonSerializer = new DataContractJsonSerializer(typeof(AsanaObjects));
var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
return jsonSerializer.ReadObject(stream) as AsanaObjects;
}
public partial class AsanaObjects
{
[DataContract]
public class Workspace
{
[DataMember]
public object id { get; set; }
[DataMember]
public string name { get; set; }
}
}
public partial class AsanaObjects
{
[DataContract]
public class Data2
{
[DataMember]
public long id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string email { get; set; }
[DataMember]
public object photo { get; set; }
[DataMember]
public Workspace[] workspaces { get; set; }
}
}
[DataContract]
public partial class AsanaObjects
{
[DataMember]
public Data2 data { get; set; }
}
}
}
我正在尝试反序列化我从 Asana API 中的 users/me 调用中获取的数据,如下所示,但该对象为 jsonResponse var 中的所有属性返回 null .数据就在那里——如果我以纯文本形式阅读它,我就能看到它。我也尝试使用 [JsonProperty("id")] 属性而不是 [DataMember] 来使用 JsonSerializer 而不是 DataContractJsonSerializer,但我得到一个例外:"Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Data2'."
我做错了什么?
注意:我一直在使用 Xamasoft JSON Class Generator 创建 classes;请参阅 GetUser 方法下方的 class。
public AsanaObjects.Data2 GetUser()
{
AsanaObjects.Data2 result = null;
string url = "https://app.asana.com/api/1.0/users/me";
try
{
var uri = new Uri(url);
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CertificateCheck);
//ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
//Must use Tls12 or else exception: "The underlying connection was closed: An unexpected error occurred on a send." InnerException = {"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."}
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.Timeout = 10000;
webRequest.Method = "GET"; webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Accept = "application/json";
//webRequest.UseDefaultCredentials = true; //doesn't seem to make a difference
webRequest.Headers.Add("Authorization", "Bearer " + AsanaBroker.Properties.Settings.Default.AccessToken);
using (var response = webRequest.GetResponse())
{
//using (var responseStream = ((HttpWebResponse)response).GetResponseStream())
//{
// if (responseStream != null)
// {
// var reader = new System.IO.StreamReader(responseStream);
// string readerText = reader.ReadToEnd();
// //Example return data: {"data":{"id":12343281337970,"name":"Eric Legault","email":"eric@foo.com","photo":null,"workspaces":[{"id":1234250096894,"name":"foo"},{"id":123446170860,"name":"Personal Projects"},{"id":12345000597911,"name":"foo2"}]}}
// }
//}
using (var responseStream = ((HttpWebResponse)response).GetResponseStream())
{
if (responseStream != null)
{
try
{
AsanaObjects.Data2 jsonResponse = null;
var jsonSerializer = new DataContractJsonSerializer(typeof(AsanaObjects.Data2));
jsonResponse = jsonSerializer.ReadObject(responseStream) as AsanaObjects.Data2;
if (jsonResponse != null)
{
result = jsonResponse;
}
}
catch (Exception ex)
{
Log.Error(ex);
}
}
}
}
}
catch (Exception ex)
{
}
return result;
}
这是我正在尝试反序列化的 class(很抱歉最初未格式化的部分 - 不确定如何修复):
public 部分 class AsanaObjects { [数据合约] public class 工作区 { [数据成员] public 对象 ID { 获取;放; }
[DataMember]
public string name { get; set; }
}
}
public partial class AsanaObjects
{
[DataContract]
public class Data2
{
[DataMember]
public long id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string email { get; set; }
[DataMember]
public object photo { get; set; }
[DataMember]
public Workspace[] workspaces { get; set; }
}
}
public partial class AsanaObjects
{
[DataMember]
public Data2[] data { get; set; }
}
data
不是数组。在您的示例中,它是单个对象。- 您想在根
AsanaObjects
class 处进行反序列化,而不是在data
class 下一级。 - 我还不得不在根
AsanaObjects
class 上抛出一个
[DataContract]
以下有效并返回一个完整的对象:
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
const string Json = @"{""data"":{""id"":12343281337970,""name"":""Eric Legault"",""email"":""eric@foo.com"",""photo"":null,""workspaces"":[{""id"":1234250096894,""name"":""foo""},{""id"":123446170860,""name"":""Personal Projects""},{""id"":12345000597911,""name"":""foo2""}]}}";
static void Main(string[] args)
{
var theReturn = DeserializeJson(Json);
}
private static AsanaObjects DeserializeJson(string json) {
var jsonSerializer = new DataContractJsonSerializer(typeof(AsanaObjects));
var stream = new MemoryStream(Encoding.UTF8.GetBytes(json));
return jsonSerializer.ReadObject(stream) as AsanaObjects;
}
public partial class AsanaObjects
{
[DataContract]
public class Workspace
{
[DataMember]
public object id { get; set; }
[DataMember]
public string name { get; set; }
}
}
public partial class AsanaObjects
{
[DataContract]
public class Data2
{
[DataMember]
public long id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string email { get; set; }
[DataMember]
public object photo { get; set; }
[DataMember]
public Workspace[] workspaces { get; set; }
}
}
[DataContract]
public partial class AsanaObjects
{
[DataMember]
public Data2 data { get; set; }
}
}
}