es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Deserializar JSON con un arreglo en DataTable?

Sé que esta pregunta es muy popular aquí en StackOverflow, pero no puedo encontrar una solución adecuada… He revisado prácticamente todas las preguntas relacionadas con esto, he probado casi todos los métodos, pero ninguno ha funcionado…

Al parecer, mi problema es que tengo arrays dentro de mi JSON y el deserializador de JSON.Net no lo acepta en absoluto. Así que, mi última opción es publicar una pregunta yo mismo.

Aquí está mi JSON:

{
  "artists": [
    {
      "Name": "artista",
      "URL": "www.example.com",
      "Desc": "artista muy bueno",
      "Rating": 5,
      "NSFW": false,
      "Tags": ["bueno", "épico"],
      "fav": true
    },
    {
      "Name": "otro artista",
      "URL": "www.test.net",
      "Desc": "súper genial",
      "Rating": 3,
      "NSFW": true,
      "Tags": ["digital", "comisiones"],
      "fav": false
    }
  ]
}

Y aquí está mi código en C#:
“`c#
using StreamReader r = new StreamReader("C:\ruta\hacia\archivo.json");
string json = r.ReadToEnd();
DataTable dt = JsonConvert.DeserializeObject<datatable>(json);

<pre><code>Pero cuando intento ejecutarlo, obtengo la siguiente excepción:
“`code
Newtonsoft.Json.JsonSerializationException: ‘Símbolo JSON inesperado al leer DataTable. Se esperaba StartArray, se obtuvo StartObject. Ruta ”, línea 1, posición 1.’

En esta pregunta en particular, hay una respuesta que intenta solucionar este mismo problema que tengo, pero lamentablemente no pude hacer que funcionara.

Créeme, he intentado todo lo que parecía adecuado para este problema y aún no puedo resolverlo, por favor ayuda. No incluiré el código que he utilizado para otras soluciones a este problema, como deserializarlo a una clase personalizada, porque eso haría todo aún más confuso. Estoy usando Visual Studio 2022, .NET 6.0 en un proyecto de WinForms.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Si estás intentando deserializar JSON con matrices a un DataTable usando C# y Json.net y te encuentras con una excepción como “Se esperaba StartArray, se obtuvo StartObject”, el problema probablemente esté en la estructura del JSON.

    La razón de esta excepción es que Json.net espera que una matriz comience con el carácter “[” y no con el carácter “{“. En el JSON proporcionado, la propiedad “artists” es una matriz de objetos JSON, pero el deserializador está tratando de considerarla como un solo objeto JSON, lo cual es incorrecto.

    Una solución a este problema es deserializar primero el JSON a una clase personalizada que represente la estructura del JSON y luego convertirla en un DataTable usando LINQ. Aquí tienes un ejemplo de código que demuestra esto:

    “`c#
    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.IO;
    using System.Linq;

    namespace JsonToDataTable
    {
    class Program
    {
    static void Main(string[] args)
    {
    string jsonFilePath = @”C:\ruta\al\archivo.json”;

            // Deserializar el JSON a una clase personalizada
            JsonData jsonData = JsonConvert.DeserializeObject<jsondata>(File.ReadAllText(jsonFilePath));
    
            // Convertir la clase personalizada en un DataTable usando LINQ
            DataTable dataTable = new DataTable();
    
            foreach (var propiedad in jsonData.artists[0].GetType().GetProperties())
            {
                dataTable.Columns.Add(propiedad.Name, propiedad.PropertyType);
            }
    
            foreach (var obj in jsonData.artists)
            {
                DataRow fila = dataTable.NewRow();
                foreach (var propiedad in obj.GetType().GetProperties())
                {
                    fila[propiedad.Name] = propiedad.GetValue(obj);
                }
                dataTable.Rows.Add(fila);
            }
    
            // Mostrar el DataTable
            foreach (DataRow fila in dataTable.Rows)
            {
                foreach (DataColumn columna in dataTable.Columns)
                {
                    Console.Write($"{columna.ColumnName}: {fila[columna]} ");
                }
                Console.WriteLine();
            }
    
            Console.ReadLine();
        }
    }
    
    public class JsonData
    {
        public List<artist> artists { get; set; }
    }
    
    public class Artist
    {
        public string Name { get; set; }
        public string URL { get; set; }
        public string Desc { get; set; }
        public int Rating { get; set; }
        public bool NSFW { get; set; }
        public List<string> Tags { get; set; }
        public bool fav { get; set; }
    }
    

    }
    “`

    El código anterior define una clase personalizada para el JSON, JsonData, que tiene una propiedad artists que es una lista de objetos Artist. La clase Artist define la estructura de los objetos JSON dentro de la matriz artists.

    El código luego deserializa el JSON a una instancia de JsonData utilizando JsonConvert.DeserializeObject<jsondata>. El siguiente paso es convertir la lista artists en un DataTable usando LINQ.

    El primer bucle foreach itera sobre las propiedades de la clase Artist y agrega columnas al DataTable con los mismos nombres y tipos. El segundo bucle foreach itera sobre la lista artists y agrega filas al DataTable con los valores de las propiedades de cada objeto Artist.

    Finalmente, el DataTable se muestra en la consola.

    Espero que esta solución te ayude a deserializar tu JSON con matrices a un DataTable usando C# y Json.net.

Comments are closed.