如何在C#中反序列化自定义json

时间:2018-02-23 21:03:33

标签: c# json

我正在尝试反序列化一个JSON文件,其元素的格式如下:

{"include\\fooo\\Gell.h": {
    "parents": [
        "include\\rfg\\ExplorableMa.h"
    ],
    "children": [
        "include\\rfg\\IEditable.h",
        "include\\rfg\\IExplorable.h",
        "Bar"
    ]
}}

JSON文件中可能有一个或多个元素彼此跟随。我尝试使用System.Runtime.Serialization.Json命名空间,但我对此代码没有太大成功:

[DataContract]
class Vertex
{
    [DataMember] public string Path { get; set; }
}

using (Stream stream = File.OpenRead(@"file.json"))
{
    var serializer = new DataContractJsonSerializer(typeof(Vertex[]));
    Vertex[] verteces = (Vertex[])serializer.ReadObject(stream);
    // the array is not valid at this point
}

上面的代码应该用一个顶点填充数组,并且在这个特定情况下它的路径等于"include\\fooo\\Gell.h"才能开始。 反序列化这样的JSON文件的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

使用Json.Net,您可以通过这种方式(或类似)反序列化您的文件:

using System.Collections.Generic;
using System.Windows;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

class Vertex
{
    [JsonExtensionData]
    public IDictionary<string, JToken> _additionalData;
}

var content = File.ReadAllText(@"file.json");
var d = JsonConvert.DeserializeObject<Vertex>(content);

看一下这些例子:http://james.newtonking.com/archive/2013/05/08/json-net-5-0-release-5-defaultsettings-and-extension-data

答案 1 :(得分:0)

首先,请注意您的根JSON容器是一个对象,而不是一个数组。 JSON standard指定以下类型的容器:

  • 有序集合值的数组。数组以[(左括号)开头,以](右括号)结尾。值以,(逗号)分隔。

    大多数JSON序列化程序将.Net枚举映射到JSON数组。

  • 该对象是一组无序的名称/值对。对象以{(左大括号)开头,以}(右大括号)结束。

    大多数JSON序列化程序将字典和非可枚举的非基本类型映射到JSON对象。

因此,您需要反序列化为另一种类型,一种映射到具有自定义,可变属性名称且具有固定模式值的对象。在这种情况下,大多数序列化程序都支持Dictionary<string, TValue>

首先定义以下类型:

public class VertexData
{
    public List<string> parents { get; set; }
    public List<string> children { get; set; }
}

然后,使用,您可以按照以下反序列化为Dictionary<string, VertexData>,只要您使用的是.Net 4.5或更高版本,如this answer中所述:

var serializer = new DataContractJsonSerializer(typeof(Dictionary<string, VertexData>)) { UseSimpleDictionaryFormat = true };
var vertices = (Dictionary<string, VertexData>)serializer.ReadObject(stream);
var paths = vertices.Keys.ToList();

如果您希望使用,可以deserialize使用Dictionary<string, VertexData>,如下所示:

using (var reader = new StreamReader(stream))
using (var jsonReader = new JsonTextReader(reader))
{
    var vertices = JsonSerializer.CreateDefault().Deserialize<Dictionary<string, VertexData>>(jsonReader);
    var paths = vertices.Keys.ToList();
}

最后使用

using (var reader = new StreamReader(stream))
{
    var jsonString = reader.ReadToEnd();

    var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
    var vertices = serializer.Deserialize<Dictionary<string, VertexData>>(jsonString);
    var paths = vertices.Keys.ToList();
}