【问题标题】:Deserializing JSON with numeric string keys in C#在 C# 中使用数字字符串键反序列化 JSON
【发布时间】:2022-02-09 06:35:48
【问题描述】:
{
  Items: [
    {
      "title": "Object1",
      "preview": {
        "2048": "preview_9212.jpg",
        "1024": "preview_6693.jpg",
      }
    },
    {
      "title": "Object2",
      "preview": {
        "2048": "preview_9888.jpg",
        "1024": "preview_6890.jpg",
      }
    },
    {
      "title": "Object3",
      "preview": {
        "2048": "preview_9822.jpg",
        "1024": "preview_6848.jpg",
      }
    }
  ]
}

我通常这样反序列化:

[Serializable]
public class JsonParser
{
    public string title;
    public List<Preview> preview;
}

[Serializable]
class Preview
{
    public string 2048;
} 

但是由于 2048 是一个 Integer 是不可能使用这种方式的。 我尝试反序列化 JSON 以获得如下预览:

public class Preview
{
  [JsonProperty("2048")]
  public string imageNumber { get; set; }
}

var user = JsonConvert.DeserializeObject<Preview>(jsonValue);

var json = JObject.Parse(jsonValue);
var preview = json["preview"].ToObject<Dictionary<string, string>>();
foreach (var entry in preview)
{
    Debug.Log(entry.Key);
    Debug.Log(entry.Value);
}

我得到:NullReferenceException:对象引用未设置为对象的实例。

我也试过 Deserializing JSON that has an int as a key in C# 但又是 NullReferenceException;

感谢您的帮助!

【问题讨论】:

  • JsonProperty 属性并不像您认为的那样。你需要反序列化整个东西,然后从反序列化的对象中获取你想要的数据。
  • 你的 json 字符串比你的编码类型有更多的嵌套级别。也许你可以尝试一些 json 路径
  • 看看herehere
  • @RobertHarvey 问题出在那些关键不是整数。
  • 显示的 JSON 无效(Items 周围没有引号),并且由于属性名称不同(其中两个对象具有 "title",一个具有 "type")而难以反序列化。请编辑您的标题,因为没有整数键;有数字字符串键。类似的问题,不同的描述。

标签: c# json deserialization


【解决方案1】:

由于您有数字字符串属性,因此您有 2 个主要选择:

  1. 使用类似 [JsonProperty("2048")] 并为属性选择有效名称

  2. 或者使用字典。这对我来说看起来更灵活,所以你可以试试这个代码

Data data= JsonConvert.DeserializeObject<Data>(json);

string preview2048 = data.Items[0].Preview["2048"];  //preview_9212.jpg

使用 Linq 进行更复杂的搜索

string  obj3Preview2048 = data.Items.Where(i=> i.Title == "Object3")
.Select(i =>i.Preview["2048"]).FirstOrDefault(); //preview_9822.jpg

public partial class Data
{
    [JsonProperty("Items")]
    public List<Item> Items { get; set; }
}

public partial class Item
{
    [JsonProperty("title", NullValueHandling = NullValueHandling.Ignore)]
    public string Title { get; set; }

    [JsonProperty("token")]
    public string Token { get; set; }

    [JsonProperty("preview")]
    public Dictionary<string, string> Preview { get; set; }
}

并且您在发布的 json 中有一些拼写错误,我在其中一个 json 对象中将“类型”修复为“标题”。这是固定版本

{
    "Items": [{
            "title": "Object1",
            "token": "6561b1bbe5f1958848jhgd43d2",
            "preview": {
                "2048": "preview_9212.jpg",
                "1024": "preview_6693.jpg"
            }
        },
        {
            "title": "Object2",
            "token": "4a42eb54648DSFhUI664654d25",
            "preview": {
                "2048": "preview_9888.jpg",
                "1024": "preview_6890.jpg"
            }
        },
        {
            "type": "Object3",
            "token": "3fba64831dghkjgfkl5dfaegoj9",
            "preview": {
                "2048": "preview_9822.jpg",
                "1024": "preview_6848.jpg"
            }
        }
    ]
}

【讨论】:

  • 没有标题为“Object3”的项目。有一个“类型”为“Object3”的项目......而且,它们是数字字符串,而不是数字。
  • 非常感谢! :)
  • @A9191 不客气。享受并请不要忘记接受答案。其他人应该知道这是一个正确的数字。您可以通过此链接了解如何接受meta.stackexchange.com/questions/5234/…
  • @HereticMonkey 感谢您提及错误。这是一个错误。
  • @HereticMonkey 谢谢你,我一定会修正我的答案。
猜你喜欢
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多