反序列化包含另一个数组的字符串数组
Deserialize string-array containing another array
好的,所以我正在努力创建一个 REST-API,并且为了为我的数据库提供种子,我使用了巨大的 JSON 文件形式的现有数据。在反序列化其中一个字段时我遇到了问题。
所以 JSON 看起来像这样:
{
"name" : "Magic 2013",
"booster" : [
"land",
"marketing",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"uncommon",
"uncommon",
"uncommon",
[
"rare",
"mythic rare"
]
]
}
当你看到这个的时候,你可能也能找出问题所在。有一个名为 booster 的字段,它是一个字符串数组……但最后一个元素不是字符串。这是另一个数组。因此,尝试将其反序列化为字符串 [] 字段失败。
我必须使用这种格式 - 我无法更改它,所以我将不得不想出一个聪明的方法来解决这个问题。这就是我需要帮助的地方。
JSON.NET 有什么方法可以反序列化吗?我可以通过某种方式进行某种手动映射,说每当我到达内部数组时,我都将执行一些自定义代码?
如有任何帮助,我将不胜感激!
谢谢!
您可以将 booster
属性 定义为 JArray
:
public JArray Booster { get; set; }
这不强制数组的特定数据类型。然后你可以遍历这个数组的每个元素(这将是一个 JToken
)并测试它是一个字符串值还是另一个 JArray
并相应地采取行动:
foreach (JToken token in model.Booster)
{
var array = token as JArray();
if (array != null)
{
// The element is an array, so you can process its subelements here
}
else
{
// It's probably a string element
string value = token.ToObject<string>();
}
}
如果它始终是最后一个包含数组而不是字符串的元素,您可以使用反序列化器
public class RootObject
{
public string name { get; set; }
public List<object> booster { get; set; }
}
然后使用
提取 booster
列表的元素
var oddItem = booster[booster.Count -1];
这是假设它始终是数组的最后一个元素
所以这对我有用:
class WhateverMyThingIsNamed
{
public string Name { get; set; }
public object[] Booster { get; set; }
public IEnumerable<string> GetBooster()
{
foreach (var o in Booster)
{
if (o is string)
{
yield return (string) o;
}
else if (o is JArray)
{
foreach (var element in (JArray) o)
{
yield return element.Value<string>();
}
}
else
{
throw new InvalidOperationException("Unexpected element");
}
}
}
}
...
var json = File.ReadAllText("json1.json");
var data = new JsonSerializer().Deserialize<WhateverMyThingIsNamed>(new JsonTextReader(new StringReader(json)));
var boosterList = data.GetBooster().ToList();
好的,所以我正在努力创建一个 REST-API,并且为了为我的数据库提供种子,我使用了巨大的 JSON 文件形式的现有数据。在反序列化其中一个字段时我遇到了问题。
所以 JSON 看起来像这样:
{
"name" : "Magic 2013",
"booster" : [
"land",
"marketing",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"uncommon",
"uncommon",
"uncommon",
[
"rare",
"mythic rare"
]
]
}
当你看到这个的时候,你可能也能找出问题所在。有一个名为 booster 的字段,它是一个字符串数组……但最后一个元素不是字符串。这是另一个数组。因此,尝试将其反序列化为字符串 [] 字段失败。
我必须使用这种格式 - 我无法更改它,所以我将不得不想出一个聪明的方法来解决这个问题。这就是我需要帮助的地方。
JSON.NET 有什么方法可以反序列化吗?我可以通过某种方式进行某种手动映射,说每当我到达内部数组时,我都将执行一些自定义代码?
如有任何帮助,我将不胜感激!
谢谢!
您可以将 booster
属性 定义为 JArray
:
public JArray Booster { get; set; }
这不强制数组的特定数据类型。然后你可以遍历这个数组的每个元素(这将是一个 JToken
)并测试它是一个字符串值还是另一个 JArray
并相应地采取行动:
foreach (JToken token in model.Booster)
{
var array = token as JArray();
if (array != null)
{
// The element is an array, so you can process its subelements here
}
else
{
// It's probably a string element
string value = token.ToObject<string>();
}
}
如果它始终是最后一个包含数组而不是字符串的元素,您可以使用反序列化器
public class RootObject
{
public string name { get; set; }
public List<object> booster { get; set; }
}
然后使用
提取booster
列表的元素
var oddItem = booster[booster.Count -1];
这是假设它始终是数组的最后一个元素
所以这对我有用:
class WhateverMyThingIsNamed
{
public string Name { get; set; }
public object[] Booster { get; set; }
public IEnumerable<string> GetBooster()
{
foreach (var o in Booster)
{
if (o is string)
{
yield return (string) o;
}
else if (o is JArray)
{
foreach (var element in (JArray) o)
{
yield return element.Value<string>();
}
}
else
{
throw new InvalidOperationException("Unexpected element");
}
}
}
}
...
var json = File.ReadAllText("json1.json");
var data = new JsonSerializer().Deserialize<WhateverMyThingIsNamed>(new JsonTextReader(new StringReader(json)));
var boosterList = data.GetBooster().ToList();