我刚刚使用all current MTG sets/cards下载了一个巨大的 JSON文件,我希望将其全部反序列化。
我已经将每个set的大部分反序列化,但是当我尝试反序列化每个Set中的booster
对象时,我遇到了麻烦:
从上面的两张图片中可以看出,每个booster
对象中都有一个字符串列表,但对于某些booster
个对象,还有一个更多字符串的附加数组。反序列化一个专门的字符串数组不是问题。当我遇到需要反序列化的booster
对象 中的字符串数组时,我的问题就出现了。
目前我设置的用于处理此反序列化的属性是:
public IEnumerable<string> booster { get; set; }
但是当我遇到booster
中有另一个数组的情况时,我会抛出一个异常,Newtonsoft.Json
抱怨它不知道如何处理反序列化。
那么,我的问题就变成了:如何反序列化字符串数组中包含的字符串数组?在C#代码中,对象需要用什么来处理那种反序列化?
答案 0 :(得分:1)
您可以将每个项目反序列化为string[]
,甚至认为该项目不是集合。因此,提供自定义序列化程序;
public class StringArrayConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JArray array = JArray.Load(reader);
for (int i = 0; i < array.Count; i++)
{
//If item is just a string, convert it string collection
if (array[i].Type == JTokenType.String)
{
array[i] = JToken.FromObject(new List<string> {array[i].ToObject<string>()});
}
}
return array.ToObject<List<string[]>>();
}
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(List<string[]>));
}
}
public class JsonObject
{
[JsonConverter(typeof(StringArrayConverter))]
public List<string[]> booster { get; set; }
}
然后反序列化json;
var data = JsonConvert.DeserializeObject<JsonObject>(json);
最后,您可以像我在下面提供的那样反序列化json;
{
"booster": [
"1",
"2",
["3","4"]
]
}
答案 1 :(得分:0)
如果您使用C#作为编程语言,请使用以下链接从JSON字符串生成C#类
然后,您可以使用代码中生成的类,使用JsonConvert.DeserializeObject(jssonstring)将json字符串反序列化为对象
答案 2 :(得分:0)
最简单的解决方案是将类型更改为IEnumerable<object>
。因此,它可以存储string
或string[]
。
或者您可以使用类型Item
和string
的两个属性创建一个类string[]
。然后你可以创建另一个属性,返回一个非空的属性,所以现在不是整个项目是object
,你可以有一个特殊的类只返回两种类型之一,所以你可以确保您获得string
或string[]
。希望这是有道理的。
您的财产:public IEnumerable<Item> booster { get; set; }
public class Item
{
private string _text;
private string[] _array;
public object Value => (object)_text ?? (object)_array;
public Item(string text) { _text = text; }
public Item(string[] array) { _array = array; }
}
当您需要使用此值时,您可以检查它的字符串或字符串[]是否如下所示:
if(myItem is string text)
{
// operate on variable text
}
else // you can be sure that myItem is of type string[] because we covered this up in the Item class
{
var array = (string[])myItem;
// operate on variable array
}
答案 3 :(得分:0)
另一个选择是建模&#34;助推器&#34;如public class ForceStringToArrayConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(IEnumerable<string[]>));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var listObject = new List<string[]>();
var jObject = JToken.Load(reader);
foreach (JToken token in jObject.Children())
{
if (token.Type == JTokenType.Array)
{
var arrayObj = (JArray)token;
listObject.Add(arrayObj.ToObject<string[]>());
}
else if (token.Type == JTokenType.String)
{
listObject.Add(new string[] { token.ToString() });
}
}
return listObject;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后使用自定义JsonConverter强制字符串到数组。在测试这个理论的过程中,我为你写了一个(经过最低限度测试但功能齐全的)转换器:)
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<YourTypeHere>(testJson, new ForceStringToArrayConverter() );
然后,当您调用DeserializeObject时,将其传递给您的自定义转换器:
id