1. Introdução
Então, você já sabe transformar objetos em JSON (e de volta). Mas o que fazer se a entrada pro seu programa for algo… estranho? Por exemplo, você esperava esse JSON:
{
"id": 123,
"name": "Alice",
"email": "alice@example.com"
}
E recebeu:
{
"name": 42,
"id": "not a number"
}
Sim, os serializers do C# vão tentar desserializar esse caos, mas muitas vezes isso leva a erros em runtime, perda de dados ou até quebra do negócio. Antes de enviar os dados adiante, salvar no banco ou mandar pela rede, verifique se os dados são válidos — senão seu código vira um acrobata sem rede de proteção.
Pra que serve a validação: é uma checagem automática de que o JSON segue regras — tipos de valores, campos obrigatórios, intervalos, estrutura etc.
2. Quais são as formas de validar JSON?
No C# e .NET existem três abordagens principais:
- Validação com código próprio: parseamos o objeto manualmente, escrevemos checks e lançamos exceptions quando algo está errado.
- Atributos de validação nos modelos: por exemplo, [Required], [Range], [EmailAddress] do namespace System.ComponentModel.DataAnnotations.
- Validação usando JSON Schema — o protagonista de hoje!
JSON Schema é um padrão que permite descrever formalmente como um documento válido deve ser. A schema também é JSON. Você define quais campos são necessários, que tipos eles têm, quais valores são permitidos, etc.
Com schemas você descreve:
- Quais campos devem estar presentes.
- Quais tipos são esperados (string, array, number, object…).
- Quais campos são obrigatórios e quais não.
- Intervalos de valores (por exemplo, idade de 0 a 150).
- Máscaras, tamanhos, listas de valores e afins.
Exemplo da schema mais simples
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string" }
},
"required": ["id", "name"]
}
3. Elementos principais do JSON Schema
Vamos entender com exemplos o que significam as chaves principais no JSON Schema.
| Chave | Descrição | Exemplo |
|---|---|---|
|
Link pra versão do padrão JSON Schema | |
|
Tipo do valor (object, array, string, number etc.) | |
|
Descrição das propriedades do objeto | |
|
Array de campos obrigatórios | |
|
Descrição do tipo dos elementos do array | |
|
Lista de valores permitidos | |
, |
Restrições pra números | |
, |
Restrições de comprimento de strings | |
|
Expressão regular pra strings | |
Visualmente: exemplo de schema pra um array de pessoas
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string", "minLength": 2, "maxLength": 50 },
"email": { "type": "string", "format": "email" }
},
"required": ["id", "name"]
}
}
4. Como validar JSON contra uma schema em C#
No .NET não há suporte nativo a JSON Schema (pelo menos até .NET 9). Na prática a galera usa bibliotecas externas: NJsonSchema ou Newtonsoft.Json.Schema (Json.NET Schema).
Instalando o pacote Newtonsoft.Json.Schema (Json.NET Schema)
Execute no terminal (na pasta do projeto):
dotnet add package Newtonsoft.Json.Schema
Importante: Newtonsoft.Json.Schema é uma biblioteca comercial (é gratuita pra uso não comercial). Pra projetos pessoais funciona muito bem.
Exemplo de checagem do JSON contra a schema
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;
string schemaJson = @"{
'type': 'object',
'properties': {
'id': { 'type': 'integer' },
'name': { 'type': 'string' },
'email': { 'type': 'string', 'format': 'email' }
},
'required': ['id', 'name']
}";
// Vamos supor que temos esse JSON
string json = @"{
'id': 123,
'name': 'Alice',
'email': 'alice@example.com'
}";
// Primeiro parseamos a schema
JSchema schema = JSchema.Parse(schemaJson);
// Parseamos o JSON em JToken
JToken jsonObj = JToken.Parse(json);
// Checamos se o JSON corresponde à schema
bool valid = jsonObj.IsValid(schema, out IList<string> errors);
if (valid)
{
Console.WriteLine("JSON é válido!");
}
else
{
Console.WriteLine("JSON NÃO é válido!");
foreach (var error in errors)
Console.WriteLine(error);
}
Como usar a validação no app?
Normalmente: primeiro validação (IsValid), depois desserialização (JsonConvert.DeserializeObject<T>) e só então a lógica de negócio. Isso elimina dados lixo cedo no fluxo.
if (jsonObj.IsValid(schema))
{
// Tudo certo, dá pra desserializar
var person = JsonConvert.DeserializeObject<Person>(json);
}
else
{
// Pare o processamento! Dados incorretos.
}
5. Uso do JSON Schema no mundo real
Quando validar?
- Ao receber dados por API (especialmente de sistemas externos e clientes diversos).
- Na migração de dados entre microservices e bancos.
- Ao gerar formulários UI dinamicamente, se a forma é construída a partir da schema.
- Em entrevistas: a pergunta "e se chegar um JSON errado?" aparece com frequência.
Ponto interessante pra curiosos
- Checagem de formatos: "format": "email", "date-time".
- Regras compostas: anyOf, oneOf, allOf.
- Validação de objetos e arrays aninhados.
- Extensões de schemas pra necessidades próprias.
6. Exemplo prático grande
Dados de entrada (lista de usuários):
[
{ "id": 1, "name": "Alice", "email": "alice@example.com" },
{ "id": 2, "name": "Bob" },
{ "id": "chto eto?", "name": 123, "email": "not-an-email" }
]
Schema:
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "integer" },
"name": { "type": "string", "minLength": 2, "maxLength": 50 },
"email": { "type": "string", "format": "email" }
},
"required": ["id", "name"]
}
}
Checagem no .NET:
string jsonArray = @"[ ... ]"; // ver acima
string schemaJson = @"{ ... }"; // ver acima
JSchema schema = JSchema.Parse(schemaJson);
JToken arrayToken = JToken.Parse(jsonArray);
bool isValid = arrayToken.IsValid(schema, out IList<string> errs);
if (!isValid)
{
foreach (var error in errs)
Console.WriteLine(error);
// Exemplos de mensagens:
// "String 'chto eto?' is not a valid integer."
// "Integer 123 is not a valid string."
// "String 'not-an-email' is not a valid email address."
}
7. Erros típicos ao trabalhar com JSON Schema
Erro #1: schema desatualizada em relação aos dados reais. Depois de mudar o modelo esquecem de atualizar a schema. A validação ou deixa passar erros ou bloqueia dados válidos.
Erro #2: mismatch de tipos entre schema e modelo. Um campo no modelo mudou de tipo (por exemplo, id virou string), mas na schema ficou integer — o validador vai reclamar.
Erro #3: falta de campos obrigatórios pro negócio. Mesmo que um campo não esteja marcado como obrigatório, a lógica pode depender dele — a ausência vai causar falhas.
Erro #4: formato de dados incorreto. Um campo do tipo string com email ou data parece "uma string", mas pode ser inválido. Use format e/ou checagens adicionais.
Erro #5: a implementação da biblioteca está atrás do padrão. O padrão evolui, e as bibliotecas nem sempre acompanham. Algumas validações podem faltar ou funcionar diferente.
GO TO FULL VERSION