尝试解释C#中的API服务器的响应时遇到了一些麻烦。
这是我们用纯JSON获得的API响应;
[
{
"response" : { "test" : "Value" }
},
{
"response" : []
}
]
如何获取Newtonsoft JSON来处理这样的响应?
目前,我将“响应”对象作为模型,一旦Newtonsoft使用JsonConvert.DeserialiseObject
处理了内容,就会收到以下错误消息。
Newtonsoft.Json.JsonSerializationException:无法将当前JSON数组(例如[1,2,3])反序列化为类型“(已编辑)”,因为该类型需要JSON对象(例如{“ name”:“ value”} )正确反序列化。 要解决此错误,可以将JSON更改为JSON对象(例如{“ name”:“ value”}),也可以将反序列化类型更改为数组,或者将实现集合接口的类型(例如ICollection,IList)更改为List,例如List从JSON数组反序列化。还可以将JsonArrayAttribute添加到类型中,以强制其从JSON数组反序列化。
答案 0 :(得分:0)
我已解决此特定问题。
通过在JsonConverter解释的字符串中添加.Replace("\"response\":[]","\"response\":{}")
。这只会在检索到的代码中解决这些特定的情况。
任何人都有一个更好的答案,这不是像这样的黑手党创可贴修复吗?
答案 1 :(得分:0)
您需要一个一个地检查响应,并根据其内容进行不同的处理。
您可以动态加载JSON,然后根据加载的内容反序列化它们。
即反序列化为对象的对象,以及反序列化为数组的数组。
以下是如何实现此目的的示例:
using System;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
var json = "[{ \"response\" : { \"test\" : \"Value1\" } }, { \"response\" : [ { \"test\" : \"Value2\" }, { \"test\" : \"Value3\" }] }]";
var responseContainers = JArray.Parse(json);
foreach(var responseContainer in responseContainers)
{
var response = responseContainer.Value<JToken>("response");
if(response.Type == JTokenType.Object)
{
var data = response.ToObject<Data>();
Console.WriteLine("data: " + data.test);
}
else if(response.Type == JTokenType.Array)
{
var dataJArray = response.ToObject<JArray>();
foreach(var dataJToken in dataJArray)
{
var data = dataJToken.ToObject<Data>();
Console.WriteLine("datas: " + data.test);
}
}
}
}
}
public class Data
{
public string test { get;set; }
}
输出:
data: Value1
datas: Value2
datas: Value3
或者,您可以使用question中的SingleOrArrayConverter
。
using System;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var json = "[{ \"response\" : { \"test\" : \"Value1\" } }, { \"response\" : [ { \"test\" : \"Value2\" }, { \"test\" : \"Value3\" }] }]";
var items = JsonConvert.DeserializeObject<List<Item>>(json);
foreach(var item in items)
{
var responses = item.response;
Console.WriteLine("ResponseCount: " + responses.Count);
foreach(var response in responses)
{
Console.WriteLine("response: " + response.test);
}
}
}
}
public class Item
{
[JsonConverter(typeof(SingleOrArrayConverter<Data>))]
public List<Data> response { get;set; }
}
public class Data
{
public string test { 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();
}
}
输出:
ResponseCount: 1
response: Value1
ResponseCount: 2
response: Value2
response: Value3