gpt4 book ai didi

c# - 无法将当前 JSON 对象反序列化为类型“WindowsService1...需要 JSON 数组(例如 [1,2,3])才能正确反序列化

转载 作者:太空宇宙 更新时间:2023-11-03 23:47:16 24 4
gpt4 key购买 nike

我有一个 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"
}
}
}
}

我的类(class)是使用 http://json2csharp.com 构建的

一切都很好,直到我

New Data allCalls = JsonConvert.DeserializeObject<Data>(json);

在数组中只获取 1 或 0 个调用(如果多于 1 个,则一切正常)。只有1次调用和0次调用时Json对象中的[]被移除,整个current_call block 不存在。

这是没有调用的样子:

 {
"response" : {
"method" : "switchvox.currentCalls.getList",
"result" : {
"current_calls" : {
"total_items" : "0"
}
}
}
}

下面是仅调用 1 次的情况:

{
"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 类型(例如,不是像整数这样的原始类型,不是集合类型像数组或列表),可以从 JSON 对象反序列化。也可以将 JsonObjectAttribute 添加到类型中以强制它从 JSON 对象反序列化。

我明白错误的含义,但我现在不知道如何根据我的情况处理它。

最佳答案

由于 current_call 有时是一个对象,有时是一个数组,有时根本不存在,您将需要使用 JsonConverter 以避免错误。您可以使用 this similar question 中的 SingleOrArrayConverter<T> 转换器并将其与 null 检查相结合以获得可行的解决方案。这是一个涵盖所有三种场景的演示:

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

关于c# - 无法将当前 JSON 对象反序列化为类型“WindowsService1...需要 JSON 数组(例如 [1,2,3])才能正确反序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27221039/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com