Como crear y leer cadenas JSON en C# con System.Text.Json
En este tutorial aprenderás a manipular cadenas JSON desde cero en c#, vamos a crear y leer cadenas JSON en C# con la librería oficial System.Text.Json.
Para empezar debemos importar la librería System.Text.Json desde el administrador de paquetes NuGet en Visual Studio para nuestra aplicación de consola y luego pasaremos al primer punto.
Si tu proyecto apunta a .NET Core 3.0 (o superior) solo se instalará una librería en caso de que sea .NET Framework 4.7 te pedirá descargar e instalar otras dependencias pero no cambia la forma de usar la librería.
Crear cadenas JSON
Para crear una cadena JSON vamos a utilizar el método
Utf8JsonWriter
que nos permite la escritura de un texto en formato JSON, inicialmente vamos a trabajar todo en memoria por lo que usaremos
MemoryStream
que nos otorga un buffer dinámico.
Los parámetros necesarios para crear una instancia de
Utf8JsonWriter
son un Stream y
JsonWriterOptions
, como mencionamos
MemoryStream
nos va a otorgar el
Stream
necesario y de tamaño variable.
El segundo es
JsonWriterOptions
que es una estructura que nos permite personalizar el comportamiento del escritor JSON y nos da 3 propiedades :
- Encoder
: Nos permite definir el codificador a usar por
Utf8JsonWriter este valor es nulo por defecto y esto indica que se utilizar el predeterminado - Indented
: Obtiene o establece un valor de tipo
bool (True o False) que le indica al escritor si debe aplicar un formato a la salida JSON como sangría a los tokens, adición de líneas nuevas y espacios, en otras palabras te muestra todo bonito. - SkipValidation : Obtiene o establece un valor de tipo bool que le indica al escritor si puede o no omitir la validación estructural permitiendo que el usuario escriba cadenas invalidas.
Ahora vamos a codificar, primero vamos a declarar el objeto de tipo
JsonWriterOptions
de nombre
jsonWOpt
y en este caso solo vamos a asignarle un valor a su propiedad
Indented= true
para que nos muestre la cadena JSON a como estamos acostumbrados.
1 2 3 | JsonWriterOptions jsonWOpt = new JsonWriterOptions { Indented = true }; |
Luego utilizando el bloque
using
vamos a crear un objeto de tipo
MemoryStream ms
que será nuestro espacio en memoria y nuevamente dentro de ese bloque utilizaremos otro bloque
using
donde vamos a crear un objeto pero ahora de tipo
Utf8JsonWriter
el cual inicializaremos con el
ms
y
jsonWOpt
.
1 2 3 4 | using (var ms = new MemoryStream()) { using (var writer = new Utf8JsonWriter(ms, jsonWOpt)) { } } |
Ahora solo queda estructurar el contenido de nuestro texto JSON, al inicio de nuestra cadena hay una llave
{
por lo que de acuerdo a la documentación de la librería utilizaremos el método
WriteStartObject()
este escribirá el principio del objeto JSON.
1 2 3 4 5 6 | using (var ms = new MemoryStream()) { using (var writer = new Utf8JsonWriter(ms, jsonWOpt)) { writer.WriteStartObject(); } } |
Después agregaremos las propiedades a nuestro objeto, en mi caso quiero poner
“nombre”
y seguido el nombre que quiera poner, por ejemplo
“scrapywar.com”
utilizando el método
WriteString
del
Utf8JsonWriter
.
1 | writer.WriteString("nombre", "scrapywar.com"); |
También agregare otro pero ahora será un numero, en mi caso una edad con el método
WriteNumber()
voy a colocar el nombre de la propiedad edad y el valor que seria 22
1 | writer.WriteNumber("edad", 22); |
Así podríamos seguir añadiendo propiedades a nuestro objeto JSON yo me conformo con esos dos para no hacer las cosas mas extensas, al terminar de agregar las propiedades vamos a añadir
WriteEndObject();
que nos dará el final del objeto
}
.
1 | writer.WriteEndObject(); |
Ahora que hemos terminado de crear el objeto JSON vamos a sacarlo de la memoria y asignarlo a una variable de tipo
string jsonstr
, para ello vamos a convertir los
bytes
almacenados en nuestro
MemoryStream ms
con la función
Encoding.UTF8.GetString()
.
1 | string jsonstr = Encoding.UTF8.GetString(ms.ToArray()); |
Al ultimo podremos imprimir la cadena para ver como quedo nuestro objeto. El código completo quedaría de la siguiente forma
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Console.WriteLine("Hello JSON!"); JsonWriterOptions jsonWOpt = new JsonWriterOptions { Indented = true }; using (var ms = new MemoryStream()) { using (var writer = new Utf8JsonWriter(ms, jsonWOpt)) { writer.WriteStartObject(); writer.WriteString("nombre", "scrapywar.com"); writer.WriteNumber("edad", 22); writer.WriteEndObject(); } string jsonstr = Encoding.UTF8.GetString(ms.ToArray()); Console.WriteLine(jsonstr); File.WriteAllText("yo.json", jsonstr); } |
Si quieres almacenar tu cadena a un archivo ya solo deberías agregar
File.WriteAllText("yo.json", jsonstr);
antes de cerrar el primer
using
, con eso se almacenara el archivo en la misma carpeta del programa con el nombre
yo.json
.
Ahora veremos como leer una cadena JSON y obtener los valores de sus propiedades.
Leyendo cadenas JSON
Anteriormente ya aprendimos a crear cadenas JSON y ahora vamos a ver como leer las propiedades que le hemos añadido, para ello ahora vamos a utilizar los métodos de
JsonDocument
que es una clase que nos permite obtener los datos de las propiedades del JSON.
En este caso mi cadena es la siguiente:
1 2 3 4 | { "nombre": "scrapywar.com", "edad": 22 } |
Primero creamos un objeto de tipo
JsonDocumentOptions JDOps
y como es una estructura le podemos personalizar las propiedades que son las siguientes:
- AllowTrailingCommas : Obtiene o establece un valor de tipo bool que indica si se permiten o se ignora una coma adicional al final de una lista de valores JSON.
- CommentHandling
: Obtiene o establece un valor que determina como maneja los comentarios, en este caso se recibe un valor de la enumeración
JsonCommentHandling que contiene:- Allow : Que permite los comentarios dentro del JSON y son tratados como tokens validos
- Disallow : Donde los comentarios causan que el JSON sea tomado como invalido y genera una excepción.
- Skip : Que permite los comentarios pero los ignora y es como sino existieran.
- MaxDepth : Obtiene o establece la profundidad máxima permitida al analizar datos JSON, y el valor predeterminado (es decir, 0) indica una profundidad máxima de 64.
Luego vamos a crear un objeto de tipo JsonDocument y lo que vamos a hacer es inicializarlo con una cadena en formato JSON la cual será analizada con
JsonDocument.Parse()
el cual tiene varias sobrecargas pero nosotros utilizaremos
Parse(String, JsonDocumentOptions)
.
El objeto
jsondoc
contiene el contenido de la cadena JSON y ahora lo trataremos como un documento, inicialmente nos debemos encontrar en la raíz del documento JSON para poder acceder a las propiedades de la misma, por lo tanto vamos a crear un
JsonElement
que nombrare
Root
que será igual al
jsondoc.RootElement;
esta función nos posiciona en la Raíz de dicho documento.
Ahora si, podemos disponer de los valores de cada propiedad, con la función
GetProperty()
que recibe como argumento el nombre de la propiedad y devuelve el valor que esta almacene.
De esa forma podemos obtener los valores de las cadenas JSON, y el código quedaría como lo siguiente:
1 2 3 4 5 6 7 | JsonDocumentOptions JDOps = new JsonDocumentOptions { AllowTrailingCommas = true }; JsonDocument jsondoc = JsonDocument.Parse(json_str,JDOps); JsonElement Root = jsondoc.RootElement; Console.WriteLine($"Nombre: {Root.GetProperty("nombre")} y edad: {Root.GetProperty("edad")}"); |
Podemos anidar los elementos en caso de que se requiera, por ejemplo para leer esta cadena:
1 2 3 4 | { "nombre":"scrapywar.com", "admins": {"usuario":"nosoyadmin","contrasena":"NoMeAcuerdo"} } |
Donde para acceder a la contraseña debemos anidar la propiedad
admins
dentro de un nuevo
JsonElement
y ese nuevo podrá acceder a la propiedad contraseña, esto se haría de la siguiente manera:
1 2 3 4 5 6 7 | JsonDocumentOptions JDOps = new JsonDocumentOptions { AllowTrailingCommas = true }; JsonDocument jsondoc = JsonDocument.Parse(json_str, JDOps); JsonElement Root = jsondoc.RootElement; JsonElement admins = Root.GetProperty("admins"); Console.WriteLine("Contraseña: " + admins.GetProperty("contrasena")); |
Ahora en caso de que tengamos un
Array
de objetos dentro de una propiedad como la siguiente cadena, donde tenemos otro objeto en
Admins
1 2 3 4 | { "nombre":"scrapywar.com", "admins": [{"usuario":"nosoyadmin","contrasena":"NoMeAcuerdo"},{"usuario":"nosoyadmin2","contrasena":"TampocoMeAcuerdo"}] } |
En este caso vamos a utilizar un
foreach
para obtener los datos de cada objeto, lo haremos de la siguiente forma:
1 2 3 4 5 6 7 8 9 10 11 | JsonDocumentOptions JDOps = new JsonDocumentOptions { AllowTrailingCommas = true }; JsonDocument jsondoc = JsonDocument.Parse(json_str, JDOps); JsonElement Root = jsondoc.RootElement; JsonElement admins = Root.GetProperty("admins"); foreach (JsonElement Jitem in admins.EnumerateArray()) { Console.WriteLine($"Usuario: {Jitem.GetProperty("usuario")} | Contraseña: {Jitem.GetProperty("contrasena")}"); } |
Espero que no haya sido tan confuso este tema aunque en la parte de abajo les dejo el proyecto de ejemplo para que lo puedan estudiar a detalle y noten como funciona.
Demo
En el siguiente Fiddle te muestro como funciona el ejemplo en .NET Core 3.1, como ya mencionaba al principio, puedes utilizar este tutorial con .NET Framework 4.7 y automáticamente se descargan las dependencias necesarias.
De esta forma es que podemos crear y leer cadenas JSON todo en C# de una forma fácil, esto nos puede ayudar en proyectos futuros, siempre puedes consultar la documentación oficial o preguntar en los comentarios.
Visita nuestra categoría C# y encuentra más tutoriales como este!
Documentación de System.Text.Json