c# linq json serialization json.net

c# - ¿Cómo compilar la jerarquía de objetos para la serialización con json.net?



linq serialization (3)

Intento escribir correctamente código para construir una estructura de datos para serializar en json.

Estoy usando json.net.

No quiero crear un grupo de clases para guardar esta información, ya que creo que debería haber algunas clases que ya lo harán en json.net

Ya obtuve todos los datos que necesito en una serie de bucles anidados, y ahora solo quiero agregarlos a una jerarquía de objetos antes de ejecutar JsonConvert.SerializeObject en él.

Ya he probado un código como este, pero parece que no funciona

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);

El problema es que cuando uso [i]. o ElementAt (i) para acceder a algún lugar de la estructura, falta .Add () o .ElementAt no está allí. ¿Cómo paso por la estructura de datos para que esto salga bien a continuación, o tengo que crear mi propia clase de contenedor para todo esto?

Este es el formato de datos que estoy tratando de hacer.

[ { "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

etc ...


Al final he usado estos Modelos.

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; }

Ahora está funcionando perfectamente. ¿Hay alguna forma mejor de hacer esto?


Creo que lo que estás preguntando es cómo serializar objetos comerciales complejos en json, pero solo exponer ciertas propiedades.

En otras palabras, ya tiene una lista de estudiantes, pero solo desea enviar datos muy específicos a través de json. Si me equivoco, esta respuesta no se ajustará a tus necesidades.

Asumiendo que tienes una lista de estudiantes, con una propiedad de proyectos que tiene una propiedad interna de tareas, así es como lo hago sin tener que crear muchas clases nuevas, utilizo objetos anónimos.

Una vez que he creado mi lista de objetos anónimos, simplemente los convierto en una cadena json.

Como se indicó en los comentarios, no es necesario que use json.net, esta funcionalidad está disponible en el marco, agregue una referencia a System.Web.Extensions.dll luego

utilizando 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);

Si realmente desea usar loops, puede hacer esto para permitirle hacer cosas más complicadas en la creación de proyectos y tareas:

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);


este es el código que genera el resultado exacto de su pregunta (requiere un 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();

Creo que el uso de la sintaxis de Json.Net Linq tiene la gran ventaja de que el código C # resultante se puede formatear de modo que casi tenga la misma estructura que el JSON que intenta generar.

ACTUALIZAR

Si desea manipular el objeto Json una vez que se ha construido, mire este ejemplo que crea la matriz externa con un solo alumno y luego agrega uno más:

// 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

La idea es que puedes aplicar el mismo principio a cualquier otra parte de la estructura de la misma manera.

HTH ...