Partilhar via


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-8de resposta . Nunca permita que a saída bruta UnsafeRelaxedJsonEscaping seja emitida para uma página HTML ou um <script> elemento.

Consulte também