c# - 问题序列化 JSON 多维列表

标签 c# .net json multidimensional-array json.net

我正在使用 JSON.Net 序列化多维列表,但在正确序列化时遇到问题。

这是我期望的结果:

     "children": [ {
        "children": [ {
           "children": [ {
              "date_added": "12995911618983970",
              "id": "8",
              "name": "NestedNestedURL",
              "type": "url",
              "url": "http://url.com/"
           } ],
           "date_added": "12995911579845538",
           "date_modified": "12995911618983970",
           "id": "5",
           "name": "NestedNestedFolder",
           "type": "folder"
        }, {
           "date_added": "12995911609609970",
           "id": "7",
           "name": "NestedURL",
           "type": "url",
           "url": "http://url.com/"
        } ],
        "date_added": "12995911570603538",
        "date_modified": "12995911609609970",
        "id": "4",
        "name": "NestedFolder",
        "type": "folder"
     }, {
        "children": [ {
           "date_added": "12995911631570970",
           "id": "9",
           "name": "NestedURL2",
           "type": "url",
           "url": "http://url.com/"
        } ],
        "date_added": "12995911589790970",
        "date_modified": "12995911631570970",
        "id": "6",
        "name": "NestedFolder2",
        "type": "folder"
     }

然而,这与我实际得到的结果有很大的不同。我认为,这里的问题是多个 URL 可以属于一个文件夹,多个文件夹可以属于一个文件夹,但我不确定如何实现这一点。这是我目前使用的代码:

public void Sync()
{
    Browser browser = new Chrome();
    SortableBindingList<Bookmark> marks = browser.ReturnBookmarks();
    SortableBindingList<object> newmarks = new SortableBindingList<object>();
    int count = 0;
   newmarks.Add(new json_top());
    json_top top = newmarks[0] as json_top;

    top.roots = new json_root();
    List<object> roots = new List<object>();

    Folder bookmarks_bar = new Folder();
    Folder other = new Folder();
    List<Object> barlist = new List<Object>();
    List<object> otherlist = new List<object>();
    List<object> children = new List<object>();
    List<string> existingFolders = new List<string>();

    bookmarks_bar.date_added = ToChromeTime(marks[0].added);
    bookmarks_bar.name = "Bookmarks bar";
    other.date_added = ToChromeTime(marks[0].added);
    other.name = "Other bookmarks";

    bool isBookmarkBar = true;

    Folder folder = new Folder();
    foreach (Bookmark mark in ordered)
    {
        List<string> fullpathlist = mark.fullPath.Split('\\').ToList();
        int count1 = 0;
        if (currentPath != mark.fullPath)
        {
            folder = (createFolder(fullpathlist, fullpathlist[0], mark));
            folder.children.Add(setChild(fullpathlist, folder, mark, 1));
            count++;
        }
        json_URL u = new json_URL();
        u.date_added = ToChromeTime(mark.added);
        u.id = id;
        u.name = mark.title;
        u.url = mark.url;
        folder.children.Add(u);
        if(isBookmarkBar)
            barlist.Add(folder);
        else
        {
            otherlist.Add(folder);
        }
    }
    bookmarks_bar.children = barlist;
    other.children = otherlist;
    top.roots.bookmark_bar = (bookmarks_bar);
    top.roots.other = other;
    string json = JsonConvert.SerializeObject(newmarks, Formatting.Indented);
    File.WriteAllText(@"c:\person.json", json);
}

    Folder setChild(List<string> fullPathList, Folder parent, Bookmark mark, int count )
    {
        if (count < fullPathList.Count)
        {
            Folder child = new Folder();
            child.date_added = ToChromeTime(mark.added);
            child.id = id;
            child.name = fullPathList[count];
            Folder LIST = setChild(fullPathList, child, mark, count + 1);
            child.children= LIST;
            return child;
        }            
    }

    public class Folder
    {
        public List<folderAndURL> children { get; set; }
        public long date_added { get; set; }
        public long date_modified
        {
            get { return 0; }
        }
        public int id { get; set; }
        public string name { get; set; }
        public string type
        {
            get { return "folder"; }
        }
    }

这是我从该代码得到的输出:

    "children": [
      {
        "children": {
          "date_added": 12995893609609970,
          "id": 0,
          "name": "NestedURL",
          "type": "url",
          "url": "http://url.com/"
        },
        "date_added": 12995893609609970,
        "date_modified": 0,
        "id": 0,
        "name": "NestedFolder",
        "type": "folder"
      },
      {
        "children": {
          "date_added": 12995893618983970,
          "id": 1,
          "name": "NestedNestedURL",
          "type": "url",
          "url": "http://url.com/"
        },
        "date_added": 12995893618983970,
        "date_modified": 0,
        "id": 1,
        "name": "NestedFolder",
        "type": "folder"
      },
      {
        "children": {
          "date_added": 12995893631570970,
          "id": 2,
          "name": "NestedURL2",
          "type": "url",
          "url": "http://url.com/"
        },
        "date_added": 12995893631570970,
        "date_modified": 0,
        "id": 2,
        "name": "NestedFolder2",
        "type": "folder"
      }

那么,如何更改我的代码以匹配输入和输出?就像我说的,这似乎是关于多个文件夹未应用于一个父文件夹的问题。

编辑:我已经上传了完整版的代码here , 因为空间原因我删掉了一些部分。

最佳答案

不知道这是不是你想要的:

/// <summary>
/// Load file from
/// C:\Users\XXXX\AppData\Local\Google\Chrome\User Data\Default\Bookmarks
/// </summary>
[TestFixture]
public class ChromeBookmarks
{
    [Test]
    public void RoundTripBookmarksTest()
    {
        JsonSerializer jsonSerializer = JsonSerializer.Create(
            new JsonSerializerSettings
                {
                    MissingMemberHandling = MissingMemberHandling.Error,
                });
        RootObject rootObject;
        using (JsonTextReader jsonTextReader = new JsonTextReader(new StringReader(Properties.Resources.Bookmarks))) //I added my bookmars as an embedded txt file for convenience
        {
            rootObject = jsonSerializer.Deserialize<RootObject>(jsonTextReader);
        }
        //Here you have the contents of the bookmarks file in rootObject if you need to do manipulations
        StringBuilder stringBuilder = new StringBuilder();
        using (JsonTextWriter jsonTextWriter = new JsonTextWriter(new StringWriter(stringBuilder)))
        {
            jsonTextWriter.Formatting = Formatting.Indented;
            jsonTextWriter.Indentation = 3;
            jsonSerializer.Serialize(jsonTextWriter, rootObject);
        }
        var json = stringBuilder.ToString();
        File.WriteAllText(@"C:\person.json", json);
    }
}
public class Child
{
    [JsonProperty(PropertyName = "children")]
    public List<Child> Children { get; set; }
    [JsonProperty(PropertyName = "date_added")]
    public string DateAdded { get; set; }
    [JsonProperty(PropertyName = "id")]
    public string Id { get; set; }
    [JsonProperty(PropertyName = "name")]
    public string Name { get; set; }
    [JsonProperty(PropertyName = "type")]
    public string Type { get; set; }
    [JsonProperty(PropertyName = "url")]
    public string Url { get; set; }
    [JsonProperty(PropertyName = "date_modified")]
    public string DateModified { get; set; }
}
public class Roots
{
    [JsonProperty(PropertyName = "bookmark_bar")]
    public Child BookmarkBar { get; set; }
    [JsonProperty(PropertyName = "other")]
    public Child Other { get; set; }
    [JsonProperty(PropertyName = "synced")]
    public Child Synced { get; set; }
}
public class RootObject
{
    [JsonProperty(PropertyName = "checksum")]
    public string Checksum { get; set; }
    [JsonProperty(PropertyName = "roots")]
    public Roots Roots { get; set; }
    [JsonProperty(PropertyName = "version")]
    public int Version { get; set; }
}

我用了this生成类,没有阅读刚刚通过我的书签的文档,所以有可能缺少某些字段。

关于c# - 问题序列化 JSON 多维列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13110222/

相关文章:

c# - 在非托管 C# .NET 库项目中使用 NuGet 库

c# - 为什么JScript中的同名变量和函数会发生冲突?

c# - 如何处理重叠但透明的图片框?

.net - Angular - 发布到 .NET Framework API 的值始终为 null

c# - 从 TableLayoutPanel 中访问组合框的 SelectedIndex

c# - CRM 2011 插件 (C#) - 遍历表单子(monad)网格中的记录

c# - 当我想要创建的类型具有不同的输入参数时,我可以使用工厂模式吗?

javascript - Angular json.data() 作为数组 []

json - 如何使用 SwiftyJson 解析 JSON

jquery - 将数据数组从 Json 传递给 wcf 函数作为参数