提问收到JSON结构

时间:2014-01-31 17:49:01

标签: c# json parsing json.net

我目前正在使用beta API(http://developer.riotgames.com/api/methods),它会为所有公开的方法返回JSON。 到目前为止,我已经能够使用JSON.NET反序列化所有这些返回值。但是,今天我消耗了他们的一个函数,它返回一个有效的JSON,但在我看来是不正确的。

你可能想知道,为什么不在测试版论坛上问它?我有,但到目前为止我还没有得到答案,总的来说这引起了我的兴趣。

JSON返回的片段:

    "1001": {
     "name": "Boots of Speed",
     "plaintext": "Slightly increases Movement Speed",
     "group": "BootsNormal",
     "description": "<...
    }

我对此结构的问题是ID被用作没有标识符的“组”。如果它有

,我将能够正常使用它
"ItemID" : "1001"

但它没有那个。我不介意手动解析它,但我首先想知道这个JSON是否正确(不仅仅是有效的)。

您是否同意这不是一种创建包含元素列表的JSON块的简洁方法,或者我在这里遗漏了什么?到目前为止,我还没有看到有关此API的beta论坛的任何评论,所以我真的很想知道为什么。

修改“有效”与“正确/可用”: 我知道这是一个有效的JSON语句。我在质疑这是否可用于JSON.NET。

我有以下类定义(带有两个子类):

public class JSONItem
{
    [JsonProperty("tags")]
    public string[] Tags { get; set; }

    [JsonProperty("plaintext")]
    public string Plaintext { get; set; }

    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("into")]
    public string[] Into { get; set; }

    [JsonProperty("image")]
    public JSONItemImage Image { get; set; }

    [JsonProperty("colloq")]
    public string Colloq { get; set; }

    [JsonProperty("gold")]
    public JSONItemGold Gold { get; set; }
}

当将上述JSON块提供给JSONConvert.DeserializeObject(json)时,它会抛出错误,因为JSONItem中未提及“1001”。 你如何处理这个问题,以便你可以使用JSON.NET?

这样的类将无效,因为您没有名称来提供属性:

public class JSONItemWrapper
{
    [JsonProperty("")]
    public string ID { get; set; }
    [JsonProperty("")]
    public JSONItem MyProperty { get; set; }
}

编辑:“与其他方法一致” 其他方法返回块,其中每个属性都在{}内并具有标识符。最近添加的函数具有“{}”样式之外的主键。

3 个答案:

答案 0 :(得分:5)

它是一个有效的json,您可以使用类似Dictionary<string, SomeObject>的类型来反序列化您的json。

string json = @"{
    ""1001"": {
            ""name"": ""Boots of Speed"",
            ""plaintext"": ""Slightly increases Movement Speed"",
            ""group"": ""BootsNormal"",
            ""description"": ""desc...""
        }
    }";


var dict = JsonConvert.DeserializeObject<Dictionary<string, MyObject>>(json); 

以后通过其键访问项目也很快。


public class MyObject
{
    public string name { get; set; }
    public string plaintext { get; set; }
    public string group { get; set; }
    public string description { get; set; }
}

答案 1 :(得分:1)

当API执行此类操作(使用数字作为属性名称)时,这很烦人,但所有内容都不会丢失。只需使用Json.NET反序列化JSON,然后使用父对象上的索引器运算符访问每个项目。

编辑:

在反序列化JSON时,我几乎从不创建DTO。在大多数情况下,这是很多不必要的样板。我更喜欢反序列化到dynamic对象,但在处理以数字开头的属性名称时这不会那么有效。

以下是我反序列化示例消息的方法:

using System;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace JsonExample
{
    internal class Program
    {
        private static void Main()
        {
            const string json = @"
                {
                    '1001': {
                        'name': 'Boots of Speed',
                        'plaintext': 'Slightly increases Movement Speed',
                        'group': 'BootsNormal',
                        'description': '<...'
                    }
                }";
            var jObject = JsonConvert.DeserializeObject<JObject>(json);
            var plaintext = jObject["1001"]["plaintext"].Value<string>();

            Console.WriteLine(plaintext);
        }
    }
}

答案 2 :(得分:0)

放入http://JSONLint.com时,

{
    "1001": {
        "name": "Boots of Speed",
        "plaintext": "Slightly increases Movement Speed",
        "group": "BootsNormal",
        "description": "<..."
    }
}

验证为JSON。