我正在尝试正确编写代码来构建数据结构以序列化为json。
我正在使用json.net。
我不想创建一堆类来保存这些数据,因为我认为应该有一些类已经在json.net中执行此操作
我已经在一系列嵌套循环中获得了所需的所有数据,现在我只想在它上运行JsonConvert.SerializeObject之前将它们添加到对象层次结构中。
我已经尝试过这样的代码,但它似乎无法正常工作
JArray container = new JArray();
container.Add(new JObject(new JProperty("name", "Client1"), new JProperty("projects", new JArray())));
container[0].AddAfterSelf(new JObject(new JProperty("projects", new JArray())));
container[1].AddAfterSelf(new JObject(new JProperty("projects", "Project2")));
container[1].AddAfterSelf(new JObject(new JProperty("projects", "Project3")));
container.Add(new JProperty("name", "Client2"));
var test = JsonConvert.SerializeObject(container);
问题是当我使用[i]时。或者ElementAt(i)访问结构中的某个地方,或者缺少.Add()或者没有.ElementAt。 如何逐步完成数据结构以使下面的输出良好,或者我是否必须为所有这些创建自己的容器类?
这是我想要制作的数据格式。
[
{
"name": "student1",
"projects":
[
{
"name": "Project1",
"tasks":
[
{
"name": "task1",
"id": 2
}
],
"id": 6
}
]
},
{
"name": "Student2",
"projects": [
{
"name": "Project1",
"tasks": [
{
"name": "Task2",
"id": 1
},
{
"name": "Task3",
"id": 3
},
{
"name": "Task4",
"id": 4
}
],
"id": 2
等...
答案 0 :(得分:34)
我认为你要问的是如何在json中序列化复杂的业务对象,但只暴露某些属性。
换句话说,您已经有了学生列表,但您只想通过json发送非常具体的数据。如果我错了,这个答案将不适合你的需要。
因此,假设您有一个学生列表,其项目属性具有任务的内部属性,这就是我不必创建大量新类的方法,我使用匿名对象。
一旦我创建了匿名对象列表,我只需将它们变成json字符串。
正如评论中指出的,你不需要使用json.net,这个功能在框架中可用,添加对System.Web.Extensions.dll
的引用然后
使用System.Web.Script.Serialization;
var jsonStudents = new List<object>();
foreach (var student in students)
{
jsonStudents.Add(new
{
student.Id, //anonymous properties automatically pick up the name of the property you pass them, this will be called Id
FullName = student.FirstName + " " + student.LastName, //if you want to name a property yourself use this notation
Projects = student.Projects.Select(p => new //this will be an enumerable of nested anonymous objects, we're partially selecting project properties
{
p.Id,
p.Name,
Tasks = p.Tasks.Select(t => new //nesting another level
{
t.Id,
t.Name
})
})
});
}
var serializer = new JavaScriptSerializer();
var jsonString = serializer.Serialize(jsonStudents);
如果你真的想使用循环,你可以这样做,让你在创建项目和任务时做更复杂的事情:
var jsonStudents = new List<object>();
foreach (var student in students)
{
var tempStudent = new
{
student.Id, //anonymous properties automatically pick up the name of the property you pass them, this will be called Id
FullName = student.FirstName + " " + student.LastName, //if you want to name a property yourself use this notation
Projects = new List<object>()
};
foreach (var project in student.Projects)
{
var tempProject = new {
project.Id,
project.Name,
Tasks = new List<object>()
};
foreach (var task in project.Tasks)
{
tempProject.Tasks.Add(new {
task.Id,
task.Name
});
}
tempStudent.Projects.Add(tempProject);
}
jsonStudents.Add(tempStudent);
}
var serializer = new JavaScriptSerializer();
var jsonString = serializer.Serialize(jsonStudents);
答案 1 :(得分:11)
这是从您的问题中生成确切输出的代码(需要using Newtonsoft.Json.Linq;
):
var json = new JArray(
new JObject(
new JProperty("name", "student1"),
new JProperty("projects",
new JArray(
new JObject(
new JProperty("name", "Project1"),
new JProperty("tasks",
new JArray(
new JObject(
new JProperty("name", "task1"),
new JProperty("id", 2)
)
)
),
new JProperty("id", 6)
)
)
)
),
new JObject(
new JProperty("name", "student2"),
new JProperty("projects",
new JArray(
new JObject(
new JProperty("name", "Project1"),
new JProperty("tasks",
new JArray(
new JObject(
new JProperty("name", "task2"),
new JProperty("id", 1)
),
new JObject(
new JProperty("name", "task3"),
new JProperty("id", 3)
),
new JObject(
new JProperty("name", "task4"),
new JProperty("id", 4)
)
)
),
new JProperty("id", 2)
)
)
)
)
);
var jsonString = json.ToString();
我相信使用Json.Net Linq语法具有很大的优势,可以对生成的C#代码进行格式化,使其几乎与您尝试生成的JSON具有相同的结构。
<强>更新强>
如果您想在构建Json对象后对其进行操作,请查看此示例,该示例仅使用一个 student 构建外部数组,然后添加另一个:
// create an isolated Student instance:
var student2 = new JObject(
new JProperty("name", "student2"),
new JProperty("projects",
new JArray(
new JObject(
new JProperty("name", "Project1"),
new JProperty("tasks",
new JArray(
new JObject(
new JProperty("name", "task2"),
new JProperty("id", 1)
),
new JObject(
new JProperty("name", "task3"),
new JProperty("id", 3)
),
new JObject(
new JProperty("name", "task4"),
new JProperty("id", 4)
)
)
),
new JProperty("id", 2)
)
)
)
);
var json = new JArray(
new JObject(
new JProperty("name", "student1"),
new JProperty("projects",
new JArray(
new JObject(
new JProperty("name", "Project1"),
new JProperty("tasks",
new JArray(
new JObject(
new JProperty("name", "task1"),
new JProperty("id", 2)
)
)
),
new JProperty("id", 6)
)
)
)
)
);
// now, add the student2 instance to the array:
json // which is an JArray
.Last // gets the last Array item, i.e. "student1"
.AddAfterSelf(student2); // adds this which hence becomes the new last one
我们的想法是,您可以以相同的方式将相同的原则应用于结构的任何其他部分。
... HTH
答案 2 :(得分:4)
最后我使用了这些模型。
public class JStudent
{
public List<JProject> projects = new List<JProject>();
public string name;
public string id;
}
public class JProject
{
public List<JTask> tasks = new List<JTask>();
public string name;
public string id;
}
public class JTask
{
public string name;
public string id;
}
它现在完美运作。有没有更好的方法呢?