100 % locale — i tuoi dati non lasciano mai il tuo browser

JSON in C# — record che System.Text.Json legge

Trasforma un campione JSON in record o classi C#. Ogni proprietà rinominata porta un attributo JsonPropertyName: il deserializzatore ritrova la sua chiave.

Istantaneo Privato Zero cookie
Stile

Input JSON

Output C#

Che cosa fa questo strumento

Un campione JSON diventa record C#, uno per oggetto.

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
using System.Text.Json.Serialization;

public record Root(
    [property: JsonPropertyName("id")] long Id,
    [property: JsonPropertyName("firstName")] string FirstName,
    [property: JsonPropertyName("address")] Address Address
);

public record Address(
    [property: JsonPropertyName("city")] string City
);

I record posizionali richiedono C# 9; lo using compare solo se compare un attributo.

Il bersaglio dell’attributo conta

I nomi delle proprietà C# sono in PascalCase: firstName diventa FirstName, e content-type diventa ContentType. System.Text.Json confronta senza distinguere maiuscole solo se glielo chiedi, e mai attraverso un trattino — perciò la chiave è fissata da un attributo.

Il prefisso property: è la parte che si sbaglia facilmente. In un record posizionale il parametro non è la proprietà: un attributo senza bersaglio resta sul parametro del costruttore, e il serializzatore non lo vede mai. Con il bersaglio finisce dove viene letto.

I tipi

  • Gli interi diventano long, i decimali double — entrambi più larghi del predefinito a 32 bit, perché un numero JSON non promette di starci.
  • null e i valori ignoti diventano object?, il che presuppone i tipi riferimento annullabili attivi (predefiniti dal .NET 6).
  • Gli array diventano List<T>; uno misto diventa List<object>, salvo quando mescola interi e decimali: lì List<double> copre entrambi.
  • Uno scalare alla radice è rifiutato: C# non ha un alias di tipo globale, quindi 42 non ha in cosa diventare. Un array di oggetti ti dà il record del suo elemento, quello che leghi a una List<Root>.

Ciò che un campione non può dire

Nessuna proprietà è annullabile oltre a quegli object?, e nessuna ha un valore predefinito: il documento aveva un valore per ciascuna. required e init valgono la pena quando saprai quali chiavi sono davvero obbligatorie — un campione dice solo quali c’erano.

Privato per progettazione

Tutto viene eseguito localmente nel browser con JavaScript. I tuoi dati non vengono mai caricati, quindi lo strumento è sicuro per contenuti sensibili e funziona anche offline.

Domande frequenti

Perché `[property: JsonPropertyName(...)]` e non solo `[JsonPropertyName(...)]`?
Perché un parametro di record posizionale non è ancora una proprietà. Senza il bersaglio `property:`, l’attributo finisce sul parametro del costruttore, dove il serializzatore non guarda mai — il compilatore avvisa perfino. Il bersaglio lo sposta sulla proprietà generata, dove `System.Text.Json` lo legge.
Uso Newtonsoft.Json. Che cosa cambio?
L’attributo e il suo using: `[property: JsonProperty("content-type")]` con `Newtonsoft.Json`. Nient’altro cambia — nomi delle proprietà, tipi e forma del record sono uguali. Newtonsoft inoltre confronta senza distinguere maiuscole per default, quindi le chiavi in `camelCase` spesso funzionano senza alcun attributo.
Record o classe?
Il record è il predefinito: uguaglianza per valore, espressioni `with` e un costruttore che rende esplicito ogni campo alla creazione. L’opzione classe dà proprietà assegnabili, ciò che si aspetta una base più vecchia o un framework che costruisce gli oggetti per assegnazione. I tipi dedotti sono identici.

Convertitori correlati