如何将包含不同数据类型的JSON数组反序列化为单个对象

时间:2016-04-07 14:24:23

标签: c# json json.net

在过去的几天里,我一直在研究如何将JSON响应反序列化为C#对象。 JSON是有效的但我无法获得任何JSON到C#转换器来转换它。我也找不到适用于此实例的Stackoverflow的答案。 JSON响应是:

[
  {
    "SEX": "Male",
    "BREED": "Opifex",
    "PVPRATING": 1301,
    "NAME": "Kilmanagh",
    "FIRSTNAME": "Big",
    "PVPTITLE": "Freshman",
    "LASTNAME": "Kahuna",
    "CHAR_DIMENSION": 5,
    "ALIENLEVEL": 30,
    "RANK_name": "Vindicator",
    "HEADID": 40281,
    "PROFNAME": "Guru",
    "LEVELX": 220,
    "PROF": "Martial Artist",
    "CHAR_INSTANCE": 12734,
    "SIDE": "Omni"
  },
  {
    "ORG_DIMENSION": 5,
    "RANK_TITLE": "President",
    "ORG_INSTANCE": 9911,
    "NAME": "Elements of Destruction",
    "RANK": 0
  },
  "2016/04/06 08:37:26"
]

从我的检查中,它是一个包含两个对象和一个字符串的数组。 我已经使用以下方法尝试将其转换为对象:

 resultArray = JsonConvert.DeserializeObject<List<JsonWhoisResult>>(data);
 and
 result = JsonConvert.DeserializeObject<JsonWhoisResult>(data);

无论哪种方式我都会收到错误:

  

转换值时出错......(剪辑)... [ConsoleApplication6.JsonWhoisResult]'。路径'',第1行,第536位。

我不知道我是否有错误的对象,或者我是否使用了这种JSON格式的错误代码。我正在使用:

public class JsonWhoisResult
{
    public stats stats { get; set; }
    public header header { get; set; }
    public string datetime { get; set; }
}

public class header
{
    public int ORG_DIMENSION { get; set; }
    public string RANK_TITLE { get; set; }
    public int ORG_INSTANCE { get; set; }
    public string NAME { get; set; }
    public int RANK { get; set; }
}

public class stats
{
    public string SEX { get; set; }
    public string BREED { get; set; }
    public int PVPRATING { get; set; }
    public string NAME { get; set; }
    public string FIRSTNAME { get; set; }
    public string PVPTITLE { get; set; }
    public string LASTNAME { get; set; }
    public int CHAR_DIMENSION { get; set; }
    public int ALIENLEVEL { get; set; }
    public string RANK_name { get; set; }
    public int HEADID { get; set; }
    public string PROFNAME { get; set; }
    public int LEVELX { get; set; }
    public string PROF { get; set; }
    public int CHAR_INSTANCE { get; set; }
    public string SIDE { get; set; }
}

如果有人有任何解决方案我会非常感激。我还有几个使用这种风格。如果我能得到解决方案,那么我应该可以将其应用到其余部分。

2 个答案:

答案 0 :(得分:3)

因为您的JSON是一个数组,所以无法反序列化为单个JsonWhoisResult,并且因为您的数组包含不同的对象类型,所以不能直接反序列化为List<JsonWhoisResult>。您需要创建自定义JsonConverter来处理这种情况。转换器可以使用Json.Net的LINQ-to-JSON API来反序列化JSON,然后手动将每个项目提取到适当的对象类型中,并根据需要填充单个JsonWhoisResult。这样的事情应该有效:

class JsonWhoisResultConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(JsonWhoisResult));
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JArray array = JArray.Load(reader);
        JsonWhoisResult result = new JsonWhoisResult();
        result.stats = array[0].ToObject<stats>();
        result.header = array[1].ToObject<header>();
        result.datetime = array[2].ToString();
        return result;
    }

    public override bool CanWrite
    {
        get { return false; }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

然后像这样使用它:

JsonWhoisResult result = JsonConvert.DeserializeObject<JsonWhoisResult>(json, new JsonWhoisResultConverter());

小提琴:https://dotnetfiddle.net/d1hkCn

答案 1 :(得分:0)

您可以使用JSON.net对dynamic的支持来执行此操作。我刚刚在上面粘贴时使用JSON测试了这个,它可以正常工作 - 但请注意,这不是强类型的。

dynamic result = JsonConvert.DeserializeObject(json);

// value is "Freshman"
Console.WriteLine("result[0].PVPTITLE = '{0}'", result[0].PVPTITLE);

// value is "President"
Console.WriteLine("result[1].RANK_TITLE = '{0}'", result[1].RANK_TITLE);

// value is 2016-04-06 08:37:27
Console.WriteLine("result[2] '{0}'", (DateTime)result[2]);