Jak dostosować kodowanie znaków za pomocą polecenia System.Text.Json
Domyślnie serializator unika wszystkich znaków innych niż ASCII. Oznacza to, że zastępuje je \uxxxx
gdzie xxxx
to kod Unicode znaku. Jeśli na przykład Summary
właściwość w następującym formacie JSON jest ustawiona na Cyrylica жарко
, WeatherForecast
obiekt jest serializowany, jak pokazano w tym przykładzie:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "\u0436\u0430\u0440\u043A\u043E"
}
Serializowanie zestawów znaków języka
Aby serializować zestawy znaków jednego lub większej liczby języków bez ucieczki, określ zakresy Unicode podczas tworzenia wystąpienia System.Text.Encodings.Web.JavaScriptEncoder, jak pokazano w poniższym przykładzie:
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)
Ten kod nie powoduje ucieczki od znaków cyrylica ani greckich. Summary
Jeśli właściwość jest ustawiona na Cyrylicaжарко
, WeatherForecast
obiekt jest serializowany, jak pokazano w tym przykładzie:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "жарко"
}
Domyślnie koder jest inicjowany z zakresem BasicLatin .
Aby serializować wszystkie zestawy języków bez ucieczki, użyj polecenia UnicodeRanges.All.
Serializowanie określonych znaków
Alternatywą jest określenie poszczególnych znaków, które mają być dozwolone bez ucieczki. Poniższy przykład serializuje tylko dwa pierwsze znaki жарко
:
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)
Oto przykład kodu JSON wygenerowanego przez powyższy kod:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "жа\u0440\u043A\u043E"
}
Listy blokowe
W poprzednich sekcjach pokazano, jak określić listy dozwolonych punktów kodu lub zakresów, których nie chcesz unikać. Istnieją jednak globalne i specyficzne dla kodera listy bloków, które mogą zastąpić niektóre punkty kodu na liście dozwolonych. Punkty kodu na liście zablokowanych są zawsze usuwane, nawet jeśli znajdują się na liście dozwolonych.
Globalna lista bloków
Globalna lista bloków zawiera takie elementy jak znaki użytku prywatnego, znaki sterujące, niezdefiniowane punkty kodu i niektóre kategorie Unicode, takie jak kategoria Space_Separator, z wyłączeniem U+0020 SPACE
. Na przykład jest on unikany, U+3000 IDEOGRAPHIC SPACE
nawet jeśli jako listę dozwolonych określisz symbole CJK zakresu Unicode i znaki interpunkcyjne (U+3000-U+303F).
Globalna lista bloków to szczegóły implementacji, które uległy zmianie w każdej wersji platformy .NET. Nie należy przyjmować zależności od znaku będącego członkiem (lub nie jest członkiem) globalnej listy bloków.
Listy blokowe specyficzne dla kodera
Przykłady zablokowanych punktów kodu specyficznych dla kodera kodera obejmują '<'
koder '&'
HTML, '\'
koder JSON i '%'
koder URL. Na przykład koder HTML zawsze unika ampersands ('&'
), mimo że ampersand znajduje się w BasicLatin
zakresie, a wszystkie kodery są inicjowane BasicLatin
domyślnie.
Serializowanie wszystkich znaków
Aby zminimalizować ucieczkę, możesz użyć metody JavaScriptEncoder.UnsafeRelaxedJsonEscaping, jak pokazano w poniższym przykładzie:
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)
Uwaga
W porównaniu z koderem domyślnym koder UnsafeRelaxedJsonEscaping
jest bardziej permisywny, dzięki czemu znaki mogą przechodzić przez niewyobrażalne:
- Nie powoduje to ucieczki znaków z uwzględnieniem kodu HTML, takich jak
<
, ,>
&
i'
. - Nie oferuje żadnych dodatkowych ochrony przed atakami XSS lub atakami ujawniania informacji, takimi jak te, które mogą wynikać z braku zgody klienta i serwera na zestaw znaków.
Użyj niebezpiecznego kodera tylko wtedy, gdy wiadomo, że klient będzie interpretował wynikowy ładunek jako kodowany kod JSON UTF-8. Na przykład można go użyć, jeśli serwer wysyła nagłówek Content-Type: application/json; charset=utf-8
odpowiedzi . Nigdy nie zezwalaj na emitowanie nieprzetworzonych UnsafeRelaxedJsonEscaping
danych wyjściowych do strony HTML lub elementu <script>
.