反序列化包含另一个数组的字符串数组

时间:2015-04-10 20:52:21

标签: c# arrays json json.net

好的,所以我正在创建一个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实际反序列化这个?有些方法我可以做某种手动映射,说每当我到达内部数组时,我会去做一些自定义代码吗?

我将不胜感激任何帮助!

谢谢!

3 个答案:

答案 0 :(得分:3)

您可以将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>();
    }
}

答案 1 :(得分:0)

如果它将始终是具有数组而不是字符串的最后一个元素,则可以使用反序列化器

public class RootObject
{
    public string name { get; set; }
    public List<object> booster { get; set; }
}

然后使用

提取booster列表的元素
var oddItem = booster[booster.Count -1];

这假设它始终是最后一个数组

答案 2 :(得分:0)

所以这对我有用:

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();