我有一个Json对象如下:
{
"response" : {
"method" : "switchvox.currentCalls.getList",
"result" : {
"current_calls" : {
"current_call" : **[**
{
"provider" : "ThinkTel",
"start_time" : "2014-11-30 02:24:52",
"duration" : "5",
"to_caller_id_number" : "800",
"state" : "ivr",
"from_caller_id_name" : "<unknown>",
"to_caller_id_name" : "Main Answer Queue",
"format" : "ulaw",
"from_caller_id_number" : "9999999999",
"id" : "SIP/1234567890-08682a00"
},
{
"provider" : "ThinkTel",
"start_time" : "2014-11-30 02:24:50",
"duration" : "7",
"to_caller_id_number" : "800",
"state" : "ivr",
"from_caller_id_name" : "<unknown>",
"to_caller_id_name" : "Main Answer Queue",
"format" : "ulaw",
"from_caller_id_number" : "1111111111",
"id" : "SIP/9876543210-08681350"
}
**]**,
"total_items" : "2"
}
}
}
}
我的课程是使用http://json2csharp.com
构建的在我的
之前一切都很好New Data allCalls = JsonConvert.DeserializeObject<Data>(json);
在数组中只获得1或0次调用(如果超过1,则全部工作)。 当只有1个调用和0个调用时,Json对象中的[]被删除,整个current_call块不存在。
以下是没有电话的情况:
{
"response" : {
"method" : "switchvox.currentCalls.getList",
"result" : {
"current_calls" : {
"total_items" : "0"
}
}
}
}
这里只有一个电话看起来如何:
{
"response" : {
"method" : "switchvox.currentCalls.getList",
"result" : {
"current_calls" : {
"current_call" : {
"provider" : "Internal",
"start_time" : "2014-11-30 19:15:44",
"duration" : "250",
"to_caller_id_number" : "777",
"state" : "talking",
"from_caller_id_name" : "<unknown>",
"to_caller_id_name" : "<unknown>",
"format" : "ulaw->ulaw",
"from_caller_id_number" : "231",
"id" : "SIP/231-b4066e90"
},
"total_items" : "1"
}
}
}
}
我收到以下错误:
无法将当前JSON对象(例如{“name”:“value”})反序列化为类型“WindowsService1.Service1 + CurrentCall []”,因为该类型需要JSON数组(例如[1,2,3])正确地反序列化。
要修复此错误,我需要将JSON更改为JSON数组(例如[1,2,3])或反序列化类型以成为正常的.NET类型(例如,不是像整数这样的基本类型,而不是集合类型像数组或List一样,可以从JSON对象反序列化。 JsonObjectAttribute也可以添加到类型中以强制它从JSON对象反序列化。
我理解错误意味着什么,但我现在不知道如何处理它。
答案 0 :(得分:3)
由于current_call
有时是一个对象,有时是一个数组,有时根本不存在,因此您需要使用JsonConverter
以避免错误。您可以使用this similar question中的SingleOrArrayConverter<T>
转换器并将其与空检查相结合,以获得可行的解决方案。这是一个涵盖所有三种场景的演示:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("--- array of calls ---");
DeserializeAndDumpCallsList(@"
{
""response"": {
""method"": ""switchvox.currentCalls.getList"",
""result"": {
""current_calls"": {
""current_call"": [
{
""provider"": ""ThinkTel"",
""start_time"": ""2014-11-30 02:24:52"",
""duration"": ""5"",
""to_caller_id_number"": ""800"",
""state"": ""ivr"",
""from_caller_id_name"": ""<unknown>"",
""to_caller_id_name"": ""Main Answer Queue"",
""format"": ""ulaw"",
""from_caller_id_number"": ""9999999999"",
""id"": ""SIP/1234567890-08682a00""
},
{
""provider"": ""ThinkTel"",
""start_time"": ""2014-11-30 02:24:50"",
""duration"": ""7"",
""to_caller_id_number"": ""800"",
""state"": ""ivr"",
""from_caller_id_name"": ""<unknown>"",
""to_caller_id_name"": ""Main Answer Queue"",
""format"": ""ulaw"",
""from_caller_id_number"": ""1111111111"",
""id"": ""SIP/9876543210-08681350""
}
],
""total_items"": ""2""
}
}
}
}");
Console.WriteLine("--- single call ---");
DeserializeAndDumpCallsList(@"
{
""response"": {
""method"": ""switchvox.currentCalls.getList"",
""result"": {
""current_calls"": {
""current_call"": {
""provider"": ""Internal"",
""start_time"": ""2014-11-30 19:15:44"",
""duration"": ""250"",
""to_caller_id_number"": ""777"",
""state"": ""talking"",
""from_caller_id_name"": ""<unknown>"",
""to_caller_id_name"": ""<unknown>"",
""format"": ""ulaw->ulaw"",
""from_caller_id_number"": ""231"",
""id"": ""SIP/231-b4066e90""
},
""total_items"": ""1""
}
}
}
}");
Console.WriteLine("--- no current call ---");
DeserializeAndDumpCallsList(@"
{
""response"": {
""method"": ""switchvox.currentCalls.getList"",
""result"": {
""current_calls"": {
""total_items"": ""0""
}
}
}
}");
}
private static void DeserializeAndDumpCallsList(string json)
{
var root = JsonConvert.DeserializeObject<RootObject>(json);
List<CurrentCall> calls = root.response.result.current_calls.current_call;
if (calls != null)
{
foreach (CurrentCall call in calls)
{
Console.WriteLine(call.from_caller_id_number);
}
}
else
{
Console.WriteLine("no calls");
}
Console.WriteLine();
}
public class RootObject
{
public Response response { get; set; }
}
public class Response
{
public string method { get; set; }
public Result result { get; set; }
}
public class Result
{
public CurrentCalls current_calls { get; set; }
}
public class CurrentCalls
{
[JsonConverter(typeof(SingleOrArrayConverter<CurrentCall>))]
public List<CurrentCall> current_call { get; set; }
public string total_items { get; set; }
}
public class CurrentCall
{
public string provider { get; set; }
public string start_time { get; set; }
public string duration { get; set; }
public string to_caller_id_number { get; set; }
public string state { get; set; }
public string from_caller_id_name { get; set; }
public string to_caller_id_name { get; set; }
public string format { get; set; }
public string from_caller_id_number { get; set; }
public string id { get; set; }
}
class SingleOrArrayConverter<T> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(List<T>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JToken token = JToken.Load(reader);
if (token.Type == JTokenType.Array)
{
return token.ToObject<List<T>>();
}
return new List<T> { token.ToObject<T>() };
}
public override bool CanWrite
{
get { return false; }
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}
输出:
--- array of calls ---
9999999999
1111111111
--- single call ---
231
--- no current call ---
no calls