JSON.net反序列化returns空对象
JSON.net deserialization returns a null object
我正在尝试扩展 HelpScoutNet 项目以便我可以利用报告。我从 HelpScout 获得的 JSON 反序列化到我的 类 中真是太糟糕了。希望你们能告诉我我做错了什么。
JSON 根据 API 文档:
{
"filterTags": [
{
"id": 123,
"name": "sample-tag"
},
...
],
"user": {
"id": 4,
"hasPhoto": true,
"createdAt": "2010-09-03T15:55:48Z",
"name": "John Smith",
"totalCustomersHelped": 6580,
"photoUrl": "http://example.com/pic.jpg"
},
"current": {
"startDate": "2015-01-01T00:00:00Z",
"endDate": "2015-01-31T23:59:59Z",
"totalDays": 30,
"resolved": 1,
"conversationsCreated": 15,
"closed": 3,
"totalReplies": 58,
"resolvedOnFirstReply": 0,
"percentResolvedOnFirstReply": 0.0,
"repliesToResolve": 2.0,
"handleTime": 78.96,
"happinessScore": 66.66666666666666,
"responseTime": 2278004,
"resolutionTime": 2278004.0,
"repliesPerDay": 1.9333333333333333,
"customersHelped": 26,
"totalConversations": 19,
"conversationsPerDay": 0.6333333333333333,
"busiestDay": 5
},
"previous": {
"startDate": "2014-01-01T00:00:00Z",
"endDate": "2014-01-31T23:59:59Z",
"totalDays": 30,
"resolved": 12,
"conversationsCreated": 2,
"closed": 33,
"totalReplies": 40,
"resolvedOnFirstReply": 4,
"percentResolvedOnFirstReply": 0.3333333333333333,
"repliesToResolve": 2.1666666666666665,
"handleTime": 0.0,
"happinessScore": 23.529411764705884,
"responseTime": 2357169,
"resolutionTime": 4318101.5,
"repliesPerDay": 1.3333333333333333,
"customersHelped": 16,
"totalConversations": 42,
"conversationsPerDay": 0.4
},
"deltas": {
"totalConversations": -54.761904761904766,
"customersHelped": 62.5,
"happinessScore": 43.13725490196077,
"repliesPerDay": 45.000000000000014,
"resolvedOnFirstReply": -100.0,
"handleTime": 0.0,
"conversationsPerDay": 58.33333333333333,
"resolved": -91.66666666666666,
"repliesToResolve": -7.692307692307687,
"activeConversations": -54.761904761904766,
"totalReplies": 44.99999999999999,
"closed": -90.9090909090909,
"responseTime": -3.3584779029420475,
"resolutionTime": -47.245241919394445,
"conversationsCreated": 650.0
}
}
JSON 我从 API:
回来
"{\"filterTags\":[{\"name\":\"general questions\",\"id\":295508},{\"name\":\"request/suggestion\",\"id\":372291},{\"name\":\"support.dd.com incorrect\",\"id\":547376},{\"name\":\"status update\",\"id\":295502},{\"name\":\"support.dd.com other\",\"id\":547378},{\"name\":\"promos/gift cards\",\"id\":295547}],\"user\":{\"createdAt\":\"2015-05-04T16:32:21Z\",\"photoUrl\":\"https://d33v4339jhl8k0.cloudfront.net/users/99999.23342.jpg\",\"hasPhoto\":true,\"name\":\"John Doe\",\"totalCustomersHelped\":261,\"id\":99999},\"current\":{\"startDate\":\"2015-08-15T12:00:00Z\",\"endDate\":\"2015-08-16T18:00:00Z\",\"totalDays\":1,\"resolved\":4,\"conversationsCreated\":0,\"closed\":11,\"totalReplies\":5,\"resolvedOnFirstReply\":3,\"percentResolvedOnFirstReply\":60.0,\"repliesToResolve\":1.25,\"handleTime\":346.6,\"happinessScore\":0.0,\"responseTime\":3467,\"resolutionTime\":4704.25,\"repliesPerDay\":5.0,\"customersHelped\":4,\"totalConversations\":12,\"conversationsPerDay\":12.0,\"busiestDay\":6}}"
我的类:
public class User
{
[DefaultValue(0)]
public int ID { get; set; }
public bool HasPhoto { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime? CreatedAt { get; set; }
public string Name { get; set; }
public int TotalCustomersHelped { get; set; }
public string PhotoURL { get; set; }
}
public class TimeRangeStats
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime? StartDate { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime? EndDate { get; set; }
public int TotalDays { get; set; }
public int Resolved { get; set; }
public int ConversationsCreated { get; set; }
public int Closed { get; set; }
public int TotalReplies { get; set; }
public int ResolvedOnFirstReply { get; set; }
public double PercentResolvedOnFirstReply { get; set; }
public double RepliesToResolve { get; set; }
public double HandleTime { get; set; }
public double HappinessScore { get; set; }
public double ResponseTime { get; set; }
public double ResolutionTime { get; set; }
public double RepliesPerDay { get; set; }
public int CustomersHelped { get; set; }
public int TotalConversations { get; set; }
public double ConversationsPerDay { get; set; }
public int BusiestDay { get; set; }
}
public class MultipleTimeRangeStats
{
public double TotalConversations { get; set; }
public double CustomersHelped { get; set; }
public double HappinessScore { get; set; }
public double RepliesPerDay { get; set; }
public double ResolvedOnFirstReply { get; set; }
public double HandleTime { get; set; }
public double ConversationsPerDay { get; set; }
public double Resolved { get; set; }
public double RepliesToResolve { get; set; }
public double ActiveConversations { get; set; }
public double TotalReplies { get; set; }
public double Closed { get; set; }
public double ResponseTime { get; set; }
public double ResolutionTime { get; set; }
public double ConversationsCreated { get; set; }
}
public class Tag
{
public string Name { get; set; }
[DefaultValue(0)]
public long ID { get; set; }
}
public class UserReport
{
public List<Tag> FilterTags { get; set; }
public User User { get; set; }
public TimeRangeStats Current { get; set; }
public TimeRangeStats Previous { get; set; }
public MultipleTimeRangeStats Deltas { get; set; }
}
序列化器设置:
private JsonSerializerSettings _serializerSettings
{
get
{
var serializer = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
};
serializer.Converters.Add(new StringEnumConverter {CamelCaseText = true});
return serializer;
}
}
我希望这不是要询问的大量信息。
HelpScoutNet:https://github.com/Selz/HelpScoutNet
相关 HelpScout API:http://developer.helpscout.net/help-desk-api/reports/user/user/
编辑:让示踪剂工作,得到这个结果。令人非常困惑的是,它找不到那些属性,但它可以在其他 类 上运行,据我所知,这些属性是相同的:
2015-08-18T00:59:30.188 Info Started deserializing HelpScoutNet.SingleItem`1[Hel
pScoutNet.Model.Report.User.UserReports.UserReport]. Path 'filterTags', line 1,
position 14.
2015-08-18T00:59:30.189 Verbose Could not find member 'filterTags' on HelpScoutN
et.SingleItem`1[HelpScoutNet.Model.Report.User.UserReports.UserReport]. Path 'fi
lterTags', line 1, position 14.
2015-08-18T00:59:30.194 Verbose Could not find member 'user' on HelpScoutNet.Sin
gleItem`1[HelpScoutNet.Model.Report.User.UserReports.UserReport]. Path 'user', l
ine 1, position 276.
2015-08-18T00:59:30.198 Verbose Could not find member 'current' on HelpScoutNet.
SingleItem`1[HelpScoutNet.Model.Report.User.UserReports.UserReport]. Path 'curre
nt', line 1, position 470.
2015-08-18T00:59:30.200 Info Finished deserializing HelpScoutNet.SingleItem`1[He
lpScoutNet.Model.Report.User.UserReports.UserReport]. Path '', line 1, position
896.
您问题中的 JSON 对应于您的 UserReport
class,而不是 SingleItem<UserReport>
-- 没有外部 {"item": ...}
容器对象。所以你需要反序列化它。
我正在尝试扩展 HelpScoutNet 项目以便我可以利用报告。我从 HelpScout 获得的 JSON 反序列化到我的 类 中真是太糟糕了。希望你们能告诉我我做错了什么。
JSON 根据 API 文档:
{
"filterTags": [
{
"id": 123,
"name": "sample-tag"
},
...
],
"user": {
"id": 4,
"hasPhoto": true,
"createdAt": "2010-09-03T15:55:48Z",
"name": "John Smith",
"totalCustomersHelped": 6580,
"photoUrl": "http://example.com/pic.jpg"
},
"current": {
"startDate": "2015-01-01T00:00:00Z",
"endDate": "2015-01-31T23:59:59Z",
"totalDays": 30,
"resolved": 1,
"conversationsCreated": 15,
"closed": 3,
"totalReplies": 58,
"resolvedOnFirstReply": 0,
"percentResolvedOnFirstReply": 0.0,
"repliesToResolve": 2.0,
"handleTime": 78.96,
"happinessScore": 66.66666666666666,
"responseTime": 2278004,
"resolutionTime": 2278004.0,
"repliesPerDay": 1.9333333333333333,
"customersHelped": 26,
"totalConversations": 19,
"conversationsPerDay": 0.6333333333333333,
"busiestDay": 5
},
"previous": {
"startDate": "2014-01-01T00:00:00Z",
"endDate": "2014-01-31T23:59:59Z",
"totalDays": 30,
"resolved": 12,
"conversationsCreated": 2,
"closed": 33,
"totalReplies": 40,
"resolvedOnFirstReply": 4,
"percentResolvedOnFirstReply": 0.3333333333333333,
"repliesToResolve": 2.1666666666666665,
"handleTime": 0.0,
"happinessScore": 23.529411764705884,
"responseTime": 2357169,
"resolutionTime": 4318101.5,
"repliesPerDay": 1.3333333333333333,
"customersHelped": 16,
"totalConversations": 42,
"conversationsPerDay": 0.4
},
"deltas": {
"totalConversations": -54.761904761904766,
"customersHelped": 62.5,
"happinessScore": 43.13725490196077,
"repliesPerDay": 45.000000000000014,
"resolvedOnFirstReply": -100.0,
"handleTime": 0.0,
"conversationsPerDay": 58.33333333333333,
"resolved": -91.66666666666666,
"repliesToResolve": -7.692307692307687,
"activeConversations": -54.761904761904766,
"totalReplies": 44.99999999999999,
"closed": -90.9090909090909,
"responseTime": -3.3584779029420475,
"resolutionTime": -47.245241919394445,
"conversationsCreated": 650.0
}
}
JSON 我从 API:
回来"{\"filterTags\":[{\"name\":\"general questions\",\"id\":295508},{\"name\":\"request/suggestion\",\"id\":372291},{\"name\":\"support.dd.com incorrect\",\"id\":547376},{\"name\":\"status update\",\"id\":295502},{\"name\":\"support.dd.com other\",\"id\":547378},{\"name\":\"promos/gift cards\",\"id\":295547}],\"user\":{\"createdAt\":\"2015-05-04T16:32:21Z\",\"photoUrl\":\"https://d33v4339jhl8k0.cloudfront.net/users/99999.23342.jpg\",\"hasPhoto\":true,\"name\":\"John Doe\",\"totalCustomersHelped\":261,\"id\":99999},\"current\":{\"startDate\":\"2015-08-15T12:00:00Z\",\"endDate\":\"2015-08-16T18:00:00Z\",\"totalDays\":1,\"resolved\":4,\"conversationsCreated\":0,\"closed\":11,\"totalReplies\":5,\"resolvedOnFirstReply\":3,\"percentResolvedOnFirstReply\":60.0,\"repliesToResolve\":1.25,\"handleTime\":346.6,\"happinessScore\":0.0,\"responseTime\":3467,\"resolutionTime\":4704.25,\"repliesPerDay\":5.0,\"customersHelped\":4,\"totalConversations\":12,\"conversationsPerDay\":12.0,\"busiestDay\":6}}"
我的类:
public class User
{
[DefaultValue(0)]
public int ID { get; set; }
public bool HasPhoto { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime? CreatedAt { get; set; }
public string Name { get; set; }
public int TotalCustomersHelped { get; set; }
public string PhotoURL { get; set; }
}
public class TimeRangeStats
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime? StartDate { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
[JsonConverter(typeof(IsoDateTimeConverter))]
public DateTime? EndDate { get; set; }
public int TotalDays { get; set; }
public int Resolved { get; set; }
public int ConversationsCreated { get; set; }
public int Closed { get; set; }
public int TotalReplies { get; set; }
public int ResolvedOnFirstReply { get; set; }
public double PercentResolvedOnFirstReply { get; set; }
public double RepliesToResolve { get; set; }
public double HandleTime { get; set; }
public double HappinessScore { get; set; }
public double ResponseTime { get; set; }
public double ResolutionTime { get; set; }
public double RepliesPerDay { get; set; }
public int CustomersHelped { get; set; }
public int TotalConversations { get; set; }
public double ConversationsPerDay { get; set; }
public int BusiestDay { get; set; }
}
public class MultipleTimeRangeStats
{
public double TotalConversations { get; set; }
public double CustomersHelped { get; set; }
public double HappinessScore { get; set; }
public double RepliesPerDay { get; set; }
public double ResolvedOnFirstReply { get; set; }
public double HandleTime { get; set; }
public double ConversationsPerDay { get; set; }
public double Resolved { get; set; }
public double RepliesToResolve { get; set; }
public double ActiveConversations { get; set; }
public double TotalReplies { get; set; }
public double Closed { get; set; }
public double ResponseTime { get; set; }
public double ResolutionTime { get; set; }
public double ConversationsCreated { get; set; }
}
public class Tag
{
public string Name { get; set; }
[DefaultValue(0)]
public long ID { get; set; }
}
public class UserReport
{
public List<Tag> FilterTags { get; set; }
public User User { get; set; }
public TimeRangeStats Current { get; set; }
public TimeRangeStats Previous { get; set; }
public MultipleTimeRangeStats Deltas { get; set; }
}
序列化器设置:
private JsonSerializerSettings _serializerSettings
{
get
{
var serializer = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
NullValueHandling = NullValueHandling.Ignore,
DefaultValueHandling = DefaultValueHandling.Ignore,
DateFormatHandling = DateFormatHandling.IsoDateFormat,
};
serializer.Converters.Add(new StringEnumConverter {CamelCaseText = true});
return serializer;
}
}
我希望这不是要询问的大量信息。
HelpScoutNet:https://github.com/Selz/HelpScoutNet
相关 HelpScout API:http://developer.helpscout.net/help-desk-api/reports/user/user/
编辑:让示踪剂工作,得到这个结果。令人非常困惑的是,它找不到那些属性,但它可以在其他 类 上运行,据我所知,这些属性是相同的:
2015-08-18T00:59:30.188 Info Started deserializing HelpScoutNet.SingleItem`1[Hel
pScoutNet.Model.Report.User.UserReports.UserReport]. Path 'filterTags', line 1,
position 14.
2015-08-18T00:59:30.189 Verbose Could not find member 'filterTags' on HelpScoutN
et.SingleItem`1[HelpScoutNet.Model.Report.User.UserReports.UserReport]. Path 'fi
lterTags', line 1, position 14.
2015-08-18T00:59:30.194 Verbose Could not find member 'user' on HelpScoutNet.Sin
gleItem`1[HelpScoutNet.Model.Report.User.UserReports.UserReport]. Path 'user', l
ine 1, position 276.
2015-08-18T00:59:30.198 Verbose Could not find member 'current' on HelpScoutNet.
SingleItem`1[HelpScoutNet.Model.Report.User.UserReports.UserReport]. Path 'curre
nt', line 1, position 470.
2015-08-18T00:59:30.200 Info Finished deserializing HelpScoutNet.SingleItem`1[He
lpScoutNet.Model.Report.User.UserReports.UserReport]. Path '', line 1, position
896.
您问题中的 JSON 对应于您的 UserReport
class,而不是 SingleItem<UserReport>
-- 没有外部 {"item": ...}
容器对象。所以你需要反序列化它。