100 % local — seus dados nunca saem do seu navegador

JSON para C# — records que o System.Text.Json lê

Transforme uma amostra JSON em records ou classes C#. Cada propriedade renomeada leva um atributo JsonPropertyName: o desserializador acha a chave dela.

Instantâneo Privado Zero cookies
Estilo

Entrada JSON

Saída C#

O que esta ferramenta faz

Uma amostra JSON vira records C#, um por objeto.

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

Os records posicionais pedem C# 9; o using só aparece se um atributo aparecer.

O alvo do atributo importa

Os nomes de propriedade do C# vão em PascalCase: firstName vira FirstName, e content-type vira ContentType. O System.Text.Json compara sem distinguir maiúsculas apenas se você pedir, e nunca através de um hífen — por isso a chave é presa com um atributo.

O prefixo property: é a parte fácil de errar. Num record posicional, o parâmetro não é a propriedade: um atributo sem alvo fica no parâmetro do construtor, e o serializador nunca o vê. Com o alvo, ele cai onde é lido.

Os tipos

  • Os inteiros viram long e os decimais double — ambos mais largos que o padrão de 32 bits, porque um número JSON não promete caber ali.
  • null e os valores desconhecidos viram object?, o que supõe tipos de referência anuláveis ligados (o padrão desde o .NET 6).
  • Os arrays viram List<T>; um array misto vira List<object>, salvo quando mistura inteiros e decimais: aí List<double> cobre os dois.
  • Um escalar na raiz é recusado: o C# não tem alias de tipo global, então 42 não tem no que virar. Um array de objetos devolve o record do seu elemento, o que você liga a uma List<Root>.

O que uma amostra não consegue dizer

Nenhuma propriedade aceita nulo além desses object?, e nenhuma tem valor padrão: o documento trazia um valor para cada uma. required e init valem a pena quando você souber quais chaves são de fato obrigatórias — uma amostra só diz quais estavam lá.

Privado por padrão

Tudo é executado localmente no seu navegador com JavaScript. Os seus dados nunca são enviados para um servidor, o que torna a ferramenta segura para conteúdo sensível e funciona offline.

Perguntas frequentes

Por que `[property: JsonPropertyName(...)]` e não só `[JsonPropertyName(...)]`?
Porque um parâmetro de record posicional ainda não é uma propriedade. Sem o alvo `property:`, o atributo cai no parâmetro do construtor, onde o serializador nunca olha — o compilador até avisa. O alvo o move para a propriedade gerada, que é onde o `System.Text.Json` o lê.
Eu uso Newtonsoft.Json. O que mudo?
O atributo e o seu using: `[property: JsonProperty("content-type")]` com `Newtonsoft.Json`. Nada mais difere — nomes de propriedade, tipos e forma do record são os mesmos. O Newtonsoft ainda compara sem distinguir maiúsculas por padrão, então chaves em `camelCase` muitas vezes funcionam sem atributo algum.
Record ou classe?
O record é o padrão: igualdade por valor, expressões `with` e um construtor que torna cada campo explícito na criação. A opção de classe dá propriedades atribuíveis, que é o que uma base mais antiga ou um framework que constrói objetos por atribuição espera. Os tipos inferidos são idênticos.

Conversores relacionados