Bagikan melalui


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.

Lihat juga