我正在使用Newtonsoft的 Json.net。
目前,我正在学习数据库存储的替代方案。我被以下问题困了 2 天:
我想以 JSON 格式在本地保存数据。我目前有以下 (xml) 结构:
<? xml version="1.0"?>
<data>
<transactions>
<transaction>
<id>1</id>
<type>1</type>
<name>a name</name>
<datetime>01-01-2017 00:00</datetime>
<amount>34,05</amount>
</transaction>
<transaction>
<id>2</id>
<type>type2</type>
<name>test transaction 2</name>
<datetime>01-02-2017 00:00</datetime>
<amount>23,03</amount>
</transaction>
</transactions>
<categories>
<category>
<id>1</id>
<name>cat 1</name>
<description>a desc for cat 1</description>
<color>red</color>
<subcategories>
<subcategory>
<id>1</id>
<name>subcat 1</name>
<description>a desc for subcat 1</description>
<color>blue</color>
</subcategory>
<subcategory>
<id>2</id>
<name>subcat 2</name>
<description>a desc for subcat 2</description>
<color>yellow</color>
</subcategory>
</subcategories>
</category>
<category>
<id>2</id>
<name>cat 2</name>
<description>a desc for cat 1</description>
<color>red</color>
</category>
</categories>
</data>
当我将以下内容转换为 JSON 结构时:
{
"data": {
"transactions": {
"transaction": [
{
"id": "1",
"type": "1",
"name": "a name",
"datetime": "01-01-2017 00:00",
"amount": "34,05"
},
{
"id": "2",
"type": "type2",
"name": "test transaction 2",
"datetime": "01-02-2017 00:00",
"amount": "23,03"
}
]
},
"categories": {
"category": [
{
"id": "1",
"name": "cat 1",
"description": "a desc for cat 1",
"color": "red",
"subcategories": {
"subcategory": [
{
"id": "1",
"name": "subcat 1",
"description": "a desc for subcat 1",
"color": "blue"
},
{
"id": "2",
"name": "subcat 2",
"description": "a desc for subcat 2",
"color": "yellow"
}
]
}
},
{
"id": "2",
"name": "cat 2",
"description": "a desc for cat 1",
"color": "red"
}
]
}
}
}
我目前遇到的问题是我可以读/写 json 文件(使用 JSON.NET)但我只能写下一个 (C#) 对象。如果我尝试将我的子类别添加到我的类别中,我会得到奇怪的结果:
法典:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace jsontest
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
List<Category> Categorylist = new List<Category>();
Category c;
SubCategory sc;
for (int i = 0; i < 5; i++)
{
// New category
c = new Category
{
id = i,
name = "Category " + i,
description = "Category description " + i,
color = Color.Red
};
//Creating a few sub categories
if (i == 2 || i == 4)
{
for (int j = 0; j < i; j++)
{
sc = new SubCategory
{
id = j,
name = "SubCategory " + j + "From Category with Id " + i,
description = "Subcategory description " + j + "from Category with Id " + i,
color = Color.Yellow
};
// Add subcategorie to category
c.subcategories.Add(sc);
}
}
// Add to list
Categorylist.Add(c);
}
string json = JsonConvert.SerializeObject(Categorylist, Newtonsoft.Json.Formatting.Indented);
richTextBox1.AppendText(Environment.NewLine + json);
}
}
public class Category
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public Color color { get; set; }
public List<SubCategory> subcategories = new List<SubCategory>();
}
public class SubCategory
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public Color color { get; set; }
}
}
结果:
[
{
"subcategories": [],
"id": 0,
"name": "Category 0",
"description": "Category description 0",
"color": "Red"
},
{
"subcategories": [],
"id": 1,
"name": "Category 1",
"description": "Category description 1",
"color": "Red"
},
{
"subcategories": [
{
"id": 0,
"name": "SubCategory 0From Category with Id 2",
"description": "Subcategory description 0from Category with Id 2",
"color": "Yellow"
},
{
"id": 1,
"name": "SubCategory 1From Category with Id 2",
"description": "Subcategory description 1from Category with Id 2",
"color": "Yellow"
}
],
"id": 2,
"name": "Category 2",
"description": "Category description 2",
"color": "Red"
},
{
"subcategories": [],
"id": 3,
"name": "Category 3",
"description": "Category description 3",
"color": "Red"
},
{
"subcategories": [
{
"id": 0,
"name": "SubCategory 0From Category with Id 4",
"description": "Subcategory description 0from Category with Id 4",
"color": "Yellow"
},
{
"id": 1,
"name": "SubCategory 1From Category with Id 4",
"description": "Subcategory description 1from Category with Id 4",
"color": "Yellow"
},
{
"id": 2,
"name": "SubCategory 2From Category with Id 4",
"description": "Subcategory description 2from Category with Id 4",
"color": "Yellow"
},
{
"id": 3,
"name": "SubCategory 3From Category with Id 4",
"description": "Subcategory description 3from Category with Id 4",
"color": "Yellow"
}
],
"id": 4,
"name": "Category 4",
"description": "Category description 4",
"color": "Red"
}
]
有人可以帮助我走上正轨吗?
如果我正确理解了这个问题,您希望在添加到 JSON 字符串后保留其格式,与第一个相同。为此,您需要创建与 JSON 对应的类。您可以使用它,然后您可以将 JSON 字符串反序列化为类的对象RootObject
并且可以轻松添加Transactions
和Categories
。下面是添加新类别的示例(添加Transactions
几乎相同):
var test = JsonConvert.DeserializeObject<RootObject>(json);
test.data.categories.category.Add(new Category()
{
id = "newId",
name = "newName",
color = "newColor",
description = "new description",
subcategories = new Subcategories()
{
subcategory = new List<Subcategory>()
}
});
test
的序列化为您提供了新的 JSON 字符串。
问题不在于 c# 代码。它按照您的指示产生输出。问题在于从 xml 到 JSON 的转换。在转换后的JSON中,subcategories
不是subcategory
数组,而是其具有属性"子类别"的对象,子类别是匿名类型的对象的"数组"。因此,如果您希望 c# 程序生成看起来像从 xml 转换后的 json 的 json 结构,那么您需要更改Category
类的定义,其中"子类别"属性不是列表类型,而是另一个复杂类型,其属性称为"子类别",反过来"子类别"将是匿名类型的数组/列表。