Como personalizar a codificação de caracteres com System.Text.Json
Por padrão, o serializador escapa de todos os caracteres não-ASCII. Ou seja, ele os substitui por \uxxxx
onde xxxx
está o código Unicode do personagem. Por exemplo, se a Summary
propriedade no JSON a seguir estiver definida como cirílico, жарко
o WeatherForecast
objeto será serializado como mostrado neste exemplo:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "\u0436\u0430\u0440\u043A\u043E"
}
Serializar conjuntos de caracteres de idioma
Para serializar os conjuntos de caracteres de um ou mais idiomas sem escapar, especifique intervalos Unicode ao criar uma instância de System.Text.Encodings.Web.JavaScriptEncoder, conforme mostrado no exemplo a seguir:
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
Imports System.Text.Encodings.Web
Imports System.Text.Json
Imports System.Text.Unicode
var options1 = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic),
WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options1);
options = New JsonSerializerOptions With {
.Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic),
.WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)
Este código não escapa aos caracteres cirílicos ou gregos. Se a Summary
propriedade for definida como cirílico, жарко
o WeatherForecast
objeto será serializado como mostrado neste exemplo:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "жарко"
}
Por padrão, o codificador é inicializado com o BasicLatin intervalo.
Para serializar todos os conjuntos de idiomas sem escapar, use UnicodeRanges.All.
Serializar caracteres específicos
Uma alternativa é especificar caracteres individuais que você deseja permitir sem escapar. O exemplo a seguir serializa apenas os dois primeiros caracteres de жарко
:
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
Imports System.Text.Encodings.Web
Imports System.Text.Json
Imports System.Text.Unicode
var encoderSettings = new TextEncoderSettings();
encoderSettings.AllowCharacters('\u0436', '\u0430');
encoderSettings.AllowRange(UnicodeRanges.BasicLatin);
var options2 = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.Create(encoderSettings),
WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options2);
Dim encoderSettings As TextEncoderSettings = New TextEncoderSettings
encoderSettings.AllowCharacters(ChrW(&H436), ChrW(&H430))
encoderSettings.AllowRange(UnicodeRanges.BasicLatin)
options = New JsonSerializerOptions With {
.Encoder = JavaScriptEncoder.Create(encoderSettings),
.WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)
Aqui está um exemplo de JSON produzido pelo código anterior:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "жа\u0440\u043A\u043E"
}
Listas de bloqueios
As seções anteriores mostram como especificar listas de permissões de pontos de código ou intervalos que você não deseja que sejam escapados. No entanto, existem listas de bloqueio globais e específicas do codificador que podem substituir determinados pontos de código na sua lista de permissões. Os pontos de código em uma lista de bloqueios são sempre escapados, mesmo que estejam incluídos na sua lista de permissões.
Lista de bloqueio global
A lista de bloqueios global inclui itens como caracteres de uso privado, caracteres de controle, pontos de código indefinidos e certas categorias Unicode, como a categoria Space_Separator, excluindo U+0020 SPACE
. Por exemplo, U+3000 IDEOGRAPHIC SPACE
é escapado mesmo se você especificar Unicode range CJK Symbols and Punctuation (U+3000-U+303F) como sua lista de permissões.
A lista de bloqueios global é um detalhe de implementação que foi alterado em todas as versões do .NET. Não dependa de um personagem ser membro (ou não ser membro) da lista de bloqueio global.
Listas de bloqueio específicas do codificador
Exemplos de pontos de código bloqueados específicos do codificador incluem '<'
e para o codificador HTML, '\'
para o codificador JSON e '%'
para o codificador'&'
de URL. Por exemplo, o codificador HTML sempre escapa de E comercial ('&'
), mesmo que o E comercial esteja no BasicLatin
intervalo e todos os codificadores sejam inicializados com BasicLatin
por padrão.
Serializar todos os caracteres
Para minimizar a fuga, você pode usar JavaScriptEncoder.UnsafeRelaxedJsonEscapingo , conforme mostrado no exemplo a seguir:
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
Imports System.Text.Encodings.Web
Imports System.Text.Json
Imports System.Text.Unicode
var options3 = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options3);
options = New JsonSerializerOptions With {
.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
.WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)
Atenção
Em comparação com o codificador padrão, o UnsafeRelaxedJsonEscaping
codificador é mais permissivo em permitir que os caracteres passem sem escapar:
- Ele não escapa de caracteres sensíveis a HTML, como
<
,>
,&
e'
. - Ele não oferece nenhuma defesa adicional profunda contra XSS ou ataques de divulgação de informações, como aqueles que podem resultar de o cliente e o servidor discordarem do charset.
Use o codificador inseguro somente quando se souber que o cliente interpretará a carga resultante como JSON codificado em UTF-8. Por exemplo, você pode usá-lo se o servidor estiver enviando o cabeçalho Content-Type: application/json; charset=utf-8
de resposta . Nunca permita que a saída bruta UnsafeRelaxedJsonEscaping
seja emitida para uma página HTML ou um <script>
elemento.