Přizpůsobení kódování znaků pomocí System.Text.Json

Ve výchozím nastavení serializátor unikne všem znakům, které nejsou ASCII. To znamená, že je nahradí \uxxxx tam, kde xxxx je kód Unicode znaku. Pokud Summary je například vlastnost v následujícím formátu JSON nastavena na cyrilice жарко, WeatherForecast objekt je serializován, jak je znázorněno v tomto příkladu:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "\u0436\u0430\u0440\u043A\u043E"
}

Serializace znakových sad jazyka

Chcete-li serializovat znakové sady jednoho nebo více jazyků bez escapingu, zadejte při vytváření instance instance znakové System.Text.Encodings.Web.JavaScriptEncodersady Unicode rozsahy, jak je znázorněno v následujícím příkladu:

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)

Tento kód neunikne cyrilice ani řecké znaky. Summary Pokud je vlastnost nastavena na cyrilice жарко, WeatherForecast objekt je serializován, jak je znázorněno v tomto příkladu:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "жарко"
}

Ve výchozím nastavení se kodér inicializuje s rozsahem BasicLatin .

Chcete-li serializovat všechny jazykové sady bez úniku, použijte UnicodeRanges.All.

Serializace konkrétních znaků

Alternativou je zadat jednotlivé znaky, které chcete povolit bez použití řídicích znaků. Následující příklad serializuje pouze první dva znaky жарко:

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)

Tady je příklad kódu JSON vytvořeného předchozím kódem:

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "жа\u0440\u043A\u043E"
}

Blokové seznamy

Předchozí části ukazují, jak zadat seznamy povolených bodů kódu nebo oblastí, které nechcete ukazovat. Existují však globální seznamy blokových seznamů a seznamů bloků specifických pro kodér, které můžou přepsat určité body kódu v seznamu povolených. Body kódu v seznamu blokovaných položek jsou vždy uchvácené, i když jsou zahrnuté do seznamu povolených položek.

Globální seznam blokovaných položek

Globální seznam blokovaných položek zahrnuje například znaky soukromého použití, řídicí znaky, nedefinované body kódu a některé kategorie Unicode, jako je například kategorie Space_Separator s výjimkou U+0020 SPACE. Je například U+3000 IDEOGRAPHIC SPACE řídicí znak, i když jako seznam povolených položek zadáte symboly CJK rozsahu Unicode a interpunkci (U+3000-U+303F).

Globální seznam blokovaných položek je podrobnosti implementace, která se změnila v každé verzi .NET. Nepoužívejte závislost na znaku, který je členem globálního seznamu blokovaných položek (nebo není členem).

Seznamy blokovaných seznamů specifických pro kodér

Mezi příklady blokovaných bodů '<''&'kódu specifických pro kodér určený pro kodér kodér a kód HTML, '\' kodér JSON a '%' pro kodér URL. Kodér HTML například vždy unikne ampersandy ('&'), i když je ampersand v rozsahu BasicLatin a všechny kodéry se inicializují ve BasicLatin výchozím nastavení.

Serializace všech znaků

Chcete-li minimalizovat zapouzdření, můžete použít JavaScriptEncoder.UnsafeRelaxedJsonEscaping, jak je znázorněno v následujícím příkladu:

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)

Upozornění

Ve srovnání s výchozím kodérem je kodér UnsafeRelaxedJsonEscaping více permisivní o povolení průchodu znaků bez neurčeného prostředí:

  • Neunikne znak citlivý na HTML, jako <je , >, &a '.
  • Nenabízí žádné další hloubkové ochrany před útoky XSS nebo únikem informací, jako jsou útoky, které můžou mít za následek nesouhlas klienta a serveru se znakovou sadou.

Nebezpečný kodér používejte jenom tehdy, když je známo, že klient bude interpretovat výslednou datovou část jako json kódovaný kódováníM UTF-8. Můžete ho použít například v případě, že server odesílá hlavičku Content-Type: application/json; charset=utf-8odpovědi . Nikdy nepovolte generování nezpracovaného UnsafeRelaxedJsonEscaping výstupu na stránku HTML nebo <script> prvek.

Viz také