【问题标题】:Deserialisation of a nested JSON object with Newtonsoft in C# [closed]在 C# 中使用 Newtonsoft 反序列化嵌套的 JSON 对象 [关闭]
【发布时间】:2014-06-30 18:51:55
【问题描述】:

这是我尝试反序列化的示例 JSON 字符串:

{
    "background": "#ededf0",
    "theme": "Flat",
    "name": "Control Page Name",
    "scriptName": "Control Page Script",
    "objects": [{
        "ID": "76799598",
        "position": {
            "top": 0.30428571428571427,
            "left": 0.6054421768707483
        },
        "width": 0.09451596023024594,
        "height": 0.07450128571428571,
        "label": "btn",
        "colour": "blue",
        "action": "OpenLayout",
        "actionParams": {
            "actionName": "Explorer",
            "itemId": "91d5bfff-a723-498a-a846-24a9e41fbaa6",
            "groupId": "bf434b0d-90c2-496a-96ce-c09f228255b4"
        }
    }]
}

我似乎无法遍历 JSON 的“对象”键节点值。单词之前的一切都很好(背景、主题、名称和脚本名称)。这是我的转换器

{
        JObject panel = (JObject)serializer.Deserialize(reader);

        var cpResponse = new VWControlPanelResponse();

        JToken scriptGroupId, scriptId;
        cpResponse.Background = (string)((JValue)panel["background"]).Value;
        cpResponse.Theme = (string)((JValue)panel["theme"]).Value;
        cpResponse.Name = (string)((JValue)panel["name"]).Value;
        cpResponse.ScriptName = (string)((JValue)panel["scriptName"]).Value;
        cpResponse.ScriptGroupId = panel.TryGetValue("scriptGroupId", out scriptGroupId) ? new Guid(scriptGroupId.ToString()) : Guid.Empty;
        cpResponse.ScriptId = panel.TryGetValue("scriptId", out scriptId) ? new Guid(scriptId.ToString()) : Guid.Empty;

        cpResponse.VisualElements = serializer.Deserialize<List<VisualElement>>(reader);


        return cpResponse;
    }

...这是我的模型:

[JsonConverter(typeof(Converter))]
public class Response
{
    public string Background { get; set; }
    public string Theme { get; set; }
    public string Name { get; set; }
    public string ScriptName { get; set; }

    public Guid ScriptGroupId { get; set; }
    public Guid ScriptId { get; set; }

    public List<VisualElement> VisualElements { get; set; }

}

public class VisualElement
{
    public long ID { get; set; }
}

}

我在网上浏览过许多类似的文章(尤其是这篇JSON Deserialization C#,但我似乎无法弄清楚为什么它不想翻译我的 VisualElements 节点。我尝试使用 reader.Read() 操作但读者的标记类型表明它是对象的结尾。

【问题讨论】:

  • 真的吗?在您的问题中,您所有的 JSON 数据都在一个 looooooooooooong 行中?谁应该阅读?
  • 编辑了您的问题并以更易读的方式格式化了 JSON 数据块...
  • 只是为了解释导致您的问题的原因(使用 LB 的答案作为解决方案):请注意,您已经反序列化了根 JSON 对象及其所有内部对象(也包括“对象”集合)第一次调用 serializer.Deserialize。当方法返回时,读者位置在 JSON 数据的末尾。因此,第二次调用 serializer.Deserialize 将不再为您提供任何数据...

标签: c# json json.net


【解决方案1】:

你可以将你的类声明为

public class Position
{
    public double top { get; set; }
    public double left { get; set; }
}

public class ActionParams
{
    public string actionName { get; set; }
    public string itemId { get; set; }
    public string groupId { get; set; }
}

public class VisualElement
{
    public string ID { get; set; }
    public Position position { get; set; }
    public double width { get; set; }
    public double height { get; set; }
    public string label { get; set; }
    public string colour { get; set; }
    public string action { get; set; }
    public ActionParams actionParams { get; set; }
}

public class Response
{
    public string background { get; set; }
    public string theme { get; set; }
    public string name { get; set; }
    public string scriptName { get; set; }
    public List<VisualElement> objects { get; set; }
}

反序列化为

 var response = JsonConvert.DeserializeObject<Response>(json);

并用作

foreach (var vObj in response.objects)
{
    Console.WriteLine(vObj.colour);
}

【讨论】:

  • 感谢您的输入,我曾经这样做并且效果很好,但理想情况下,我想集成 JSON 转换器,因为我想将位置值(顶部,左侧)转换为自定义区域对象包含这两个分数。
  • @Dramos 在不知道您的自定义 JsonConverter 做什么以及您的 Region 对象是什么的情况下,您希望我做什么?
  • 没关系,很抱歉这个误导性问题。我只是想了解为什么我不能遍历转换器内的“对象”节点。 elgonzo 给了我答案(“读者位置在 JSON 数据的末尾。因此,不会再次读取和提供数据。”)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多