Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

905
Vistas
.NET Core/System.Text.Json: Enumerar y agregar/reemplazar propiedades/valores json

En una pregunta mía anterior, pregunté cómo llenar un objeto existente usando System.Text.Json.

Una de las mejores respuestas mostró una solución que analizaba la cadena json con JsonDocument y la enumeraba con EnumerateObject .

Con el tiempo, mi cadena json evolucionó y ahora también contiene una matriz de objetos, y al analizar eso con el código de la respuesta vinculada, arroja la siguiente excepción:

 The requested operation requires an element of type 'Object', but the target element has type 'Array'.

Descubrí que uno puede, de una forma u otra, buscar JsonValueKind.Array y hacer algo como esto

 if (json.ValueKind.Equals(JsonValueKind.Array)) { foreach (var item in json.EnumerateArray()) { foreach (var property in item.EnumerateObject()) { await OverwriteProperty(???); } } }

pero no puedo hacer que funcione.

¿Cómo hacer esto, y como una solución genérica?

Me gustaría obtener el "Resultado 1" , donde se agregan/actualizan los elementos de la matriz, y el "Resultado 2" (al pasar una variable), donde se reemplaza toda la matriz.

Para el "Resultado 2" , supongo que uno puede detectar if (JsonValueKind.Array)) en el método OverwriteProperty , y ¿dónde/cómo pasar la variable "replaceArray"? ... mientras itera la matriz o los objetos?

Algunos datos de muestra:

Cadena Json inicial

 { "Title": "Startpage", "Links": [ { "Id": 10, "Text": "Start", "Link": "/index" }, { "Id": 11, "Text": "Info", "Link": "/info" } ] }

Cadena Json para agregar/actualizar

 { "Head": "Latest news", "Links": [ { "Id": 11, "Text": "News", "Link": "/news" }, { "Id": 21, "Text": "More News", "Link": "/morenews" } ] }

resultado 1

 { "Title": "Startpage", "Head": "Latest news" "Links": [ { "Id": 10, "Text": "Start", "Link": "/indexnews" }, { "Id": 11, "Text": "News", "Link": "/news" }, { "Id": 21, "Text": "More news", "Link": "/morenews" } ] }

resultado 2

 { "Title": "Startpage", "Head": "Latest news" "Links": [ { "Id": 11, "Text": "News", "Link": "/news" }, { "Id": 21, "Text": "More News", "Link": "/morenews" } ] }

Clases

 public class Pages { public string Title { get; set; } public string Head { get; set; } public List<Links> Links { get; set; } } public class Links { public int Id { get; set; } public string Text { get; set; } public string Link { get; set; } }

Código C#:

 public async Task PopulateObjectAsync(object target, string source, Type type, bool replaceArrays = false) { using var json = JsonDocument.Parse(source).RootElement; if (json.ValueKind.Equals(JsonValueKind.Array)) { foreach (var item in json.EnumerateArray()) { foreach (var property in item.EnumerateObject()) { await OverwriteProperty(???, replaceArray); //use "replaceArray" here ? } } } else { foreach (var property in json.EnumerateObject()) { await OverwriteProperty(target, property, type, replaceArray); //use "replaceArray" here ? } } return; } public async Task OverwriteProperty(object target, JsonProperty updatedProperty, Type type, bool replaceArrays) { var propertyInfo = type.GetProperty(updatedProperty.Name); if (propertyInfo == null) { return; } var propertyType = propertyInfo.PropertyType; object parsedValue; if (propertyType.IsValueType) { parsedValue = JsonSerializer.Deserialize( updatedProperty.Value.GetRawText(), propertyType); } else if (replaceArrays && "property is JsonValueKind.Array") //pseudo code sample { // use same code here as in above "IsValueType" ? } else { parsedValue = propertyInfo.GetValue(target); await PopulateObjectAsync( parsedValue, updatedProperty.Value.GetRawText(), propertyType); } propertyInfo.SetValue(target, parsedValue); }
over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Bueno, si no te importa cómo se escriben las matrices, tengo una solución simple. Cree un nuevo JSON dentro de 2 fases 1 bucle para nuevas propiedades y 1 bucle para las actualizaciones:

 var sourceJson = @" { ""Title"": ""Startpage"", ""Links"": [ { ""Id"": 10, ""Text"": ""Start"", ""Link"": ""/index"" }, { ""Id"": 11, ""Text"": ""Info"", ""Link"": ""/info"" } ] }"; var updateJson = @" { ""Head"": ""Latest news"", ""Links"": [ { ""Id"": 11, ""Text"": ""News"", ""Link"": ""/news"" }, { ""Id"": 21, ""Text"": ""More News"", ""Link"": ""/morenews"" } ] } "; using var source = JsonDocument.Parse(sourceJson); using var update = JsonDocument.Parse(updateJson); using var stream = new MemoryStream(); using var writer = new Utf8JsonWriter(stream); writer.WriteStartObject(); // write non existing properties foreach (var prop in update.RootElement.EnumerateObject().Where(prop => !source.RootElement.TryGetProperty(prop.Name, out _))) { prop.WriteTo(writer); } // make updates for existing foreach (var prop in source.RootElement.EnumerateObject()) { if (update.RootElement.TryGetProperty(prop.Name, out var overwrite)) { writer.WritePropertyName(prop.Name); overwrite.WriteTo(writer); } else { prop.WriteTo(writer); } } writer.WriteEndObject(); writer.Flush(); var resultJson = Encoding.UTF8.GetString(stream.ToArray()); Console.WriteLine(resultJson);

Producción :

 { "Head":"Latest news", "Title":"Startpage", "Links":[ { "Id":11, "Text":"News", "Link":"/news" }, { "Id":21, "Text":"More News", "Link":"/morenews" } ] }

Violín

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda