Cara menyesuaikan pengodean karakter dengan System.Text.Json
Secara default, pembuat serialisasi lolos dari semua karakter non-ASCII. Artinya, ia menggantinya dengan \uxxxx
di mana xxxx
adalah kode Unicode dari karakter. Misalnya, jika Summary
properti dalam JSON berikut diatur ke bahasa Sirilikжарко
, maka WeatherForecast
objek diserialisasikan seperti yang ditunjukkan dalam contoh ini:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "\u0436\u0430\u0440\u043A\u043E"
}
Menserialisasikan kumpulan karakter bahasa
Untuk membuat serialisasi kumpulan karakter dari satu atau beberapa bahasa tanpa melarikan diri, tentukan rentang Unicode saat membuat instans System.Text.Encodings.Web.JavaScriptEncoder, seperti yang ditunjukkan dalam contoh berikut:
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)
Kode ini tidak lolos dari karakter bahasa Sirilik atau Yunani. Jika properti Summary
diatur ke bahasa Sirilik жарко
, maka objek WeatherForecast
diserialisasikan seperti yang ditunjukkan dalam contoh ini:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "жарко"
}
Secara default, encoder diinisialisasi dengan BasicLatin rentang.
Untuk menserialisasikan semua set bahasa tanpa terluput, gunakan UnicodeRanges.All.
Menserialisasikan karakter tertentu
Alternatif berfungsi untuk menentukan karakter individual yang ingin Anda izinkan tanpa ada yang lolos. Contoh berikut hanya menserialisasikan dua karakter pertama dari жарко
:
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)
Berikut adalah contoh JSON yang dihasilkan oleh kode sebelumnya:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "жа\u0440\u043A\u043E"
}
Daftar blokir
Bagian sebelumnya memperlihatkan cara menentukan daftar titik kode yang diizinkan atau rentang yang tidak ingin Anda loloskan. Namun, ada daftar blok global dan encoder khusus yang dapat mengambil alih titik kode tertentu dalam daftar izin Anda. Titik kode dalam daftar blok selalu lolos, meskipun disertakan dalam daftar izinkan Anda.
Daftar blok global
Daftar blok global mencakup hal-hal seperti karakter penggunaan privat, karakter kontrol, titik kode yang tidak ditentukan, dan kategori Unicode tertentu, seperti kategori Space_Separator, tidak termasuk U+0020 SPACE
. Misalnya, U+3000 IDEOGRAPHIC SPACE
lolos meskipun Anda menentukan Rentang Unicode Simbol dan Tanda Baca CJK (U+3000-U+303F) sebagai daftar izin Anda.
Daftar blok global adalah detail implementasi yang telah berubah dalam setiap rilis .NET. Jangan mengambil dependensi pada karakter yang menjadi anggota (atau tidak menjadi anggota) daftar blok global.
Daftar blok khusus encoder
Contoh titik kode yang diblokir khusus encoder termasuk '<'
dan '&'
untuk encoder HTML, '\'
untuk encoder JSON, dan '%'
untuk encoder URL. Misalnya, encoder HTML selalu keluar dari ampersand ('&'
), meskipun ampersand berada dalam BasicLatin
rentang dan semua encoder diinisialisasi dengan BasicLatin
secara default.
Menserialisasikan semua karakter
Untuk meminimalkan pelepasan, Anda dapat menggunakan JavaScriptEncoder.UnsafeRelaxedJsonEscaping, seperti yang ditunjukkan dalam contoh berikut:
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)
Perhatian
Dibandingkan dengan encoder default, encoder UnsafeRelaxedJsonEscaping
lebih permisif tentang memungkinkan karakter melewati unescaped:
- Ia tidak lolos dari karakter sensitif HTML seperti
<
,>
,&
, dan'
. - Ia tidak menawarkan perlindungan pertahanan mendalam tambahan terhadap XSS atau serangan penyingkapan informasi, seperti yang mungkin diakibatkan oleh klien dan server yang tidak setuju pada charset.
Gunakan encoder yang tidak aman hanya ketika diketahui bahwa klien akan menafsirkan payload yang dihasilkan sebagai JSON yang terkode UTF-8. Misalnya, Anda dapat menggunakannya jika server mengirim header respons Content-Type: application/json; charset=utf-8
. Jangan pernah mengizinkan output mentah UnsafeRelaxedJsonEscaping
dipancarkan ke halaman HTML atau <script>
elemen.