Anpassen der Zeichencodierung mit System.Text.Json
Standardmäßig escapet der Serialisierer alle Nicht-ASCII-Zeichen. Das heißt, dass sie durch \uxxxx
ersetzt werden, wobei xxxx
der Unicode-Code des Zeichens ist. Wenn die Summary
-Eigenschaft im folgenden JSON-Code beispielsweise auf Kyrillisch жарко
festgelegt ist, wird das WeatherForecast
-Objekt wie in diesem Beispiel gezeigt serialisiert:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "\u0436\u0430\u0440\u043A\u043E"
}
Serialisieren von Sprachzeichensätzen
Zum Serialisieren der Zeichensätze von mindestens einer Sprache ohne zu escapen geben Sie Unicode-Bereiche an, wenn Sie eine Instanz von System.Text.Encodings.Web.JavaScriptEncoder erstellen, wie im folgenden Beispiel gezeigt:
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)
Mit diesem Code werden weder kyrillische noch griechische Zeichen escapet. Wenn die Summary
-Eigenschaft auf Kyrillisch жарко
festgelegt ist, wird das WeatherForecast
-Objekt wie in diesem Beispiel gezeigt serialisiert:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "жарко"
}
Standardmäßig wird der Encoder mit dem BasicLatin-Bereich initialisiert.
Um alle Sprachensätze ohne zu escapen zu serialisieren, verwenden Sie UnicodeRanges.All.
Serialisieren bestimmter Zeichen
Eine Alternative besteht darin, einzelne Zeichen anzugeben, die Sie zulassen möchten, ohne dass sie escapet werden. Im folgenden Beispiel werden nur die ersten zwei Zeichen von жарко
serialisiert:
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)
Hier sehen Sie eine JSON-Beispiel, das vom vorangehenden Code erzeugt wird:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "жа\u0440\u043A\u043E"
}
Blocklisten
In den vorherigen Abschnitten wird gezeigt, wie Sie Zulassungslisten von Codepunkten oder Bereichen angeben, die nicht mit einem Escapezeichen versehen werden sollen. Es gibt jedoch globale und encoderspezifische Blocklisten, die bestimmte Codepunkte in Ihrer Zulassungsliste außer Kraft setzen können. Codepunkte in einer Blockliste werden immer mit Escapezeichen versehen, auch wenn sie in der Zulassungsliste enthalten sind.
Globale Blockliste
Die globale Blockliste enthält Elemente wie Private-Use-Zeichen, Steuerzeichen, undefinierte Codepunkte und bestimmte Unicode-Kategorien, z. B. die Kategorie Space_Separator, ausgenommen U+0020 SPACE
. Beispielsweise wird U+3000 IDEOGRAPHIC SPACE
mit Escapezeichen versehen, auch wenn Sie den Unicode-Bereich CJK-Symbole und Interpunktion (U+3000-U+303F) als Positivliste angeben.
Die globale Blockliste ist ein Implementierungsdetail, das sich in jedem Release von .NET geändert hat. Verwenden Sie keine Abhängigkeit von einem Zeichen, das Member (oder kein Member) der globalen Blockliste ist.
Encoderspezifische Blocklisten
Beispiele für encoderspezifische blockierte Codepunkte sind '<'
und '&'
für den HTML-Encoder, '\'
für den JSON-Encoder und '%'
für den URL-Encoder. Der HTML-Encoder z. B. versieht kaufmännische Und-Zeichen ('&'
) immer mit Escapezeichen, obwohl sich das kaufmännische Und-Zeichen im BasicLatin
-Bereich befindet und alle Encoder standardmäßig mit BasicLatin
initialisiert werden.
Serialisieren aller Zeichen
Um das Escapen zu minimieren, können Sie JavaScriptEncoder.UnsafeRelaxedJsonEscaping verwenden, wie im folgenden Beispiel gezeigt:
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)
Achtung
Im Vergleich zum Standardencoder ist der UnsafeRelaxedJsonEscaping
-Encoder weniger streng beim Zulassen von Zeichen, ohne sie zu escapen:
- Er escapet keine HTML-abhängigen Zeichen wie
<
,>
,&
und'
. - Er bietet keine zusätzlichen, tief greifenden Abwehrmaßnahmen gegen solche Cross-Site Scripting (XSS)- oder Information-Disclosure-Angriffe (Veröffentlichung von Informationen), die von einem Client und Server, die sich nicht auf einen Zeichensatz einigen können, verursacht werden können.
Verwenden Sie den unsicheren Encoder nur dann, wenn bekannt ist, dass der Client die resultierende Nutzlast als UTF-8-codiertes JSON interpretieren wird. Beispielsweise können Sie ihn verwenden, wenn der Server den Antwortheader Content-Type: application/json; charset=utf-8
sendet. Gestatten Sie niemals, dass die UnsafeRelaxedJsonEscaping
-Rohausgabe in eine HTML-Seite oder ein <script>
-Element ausgegeben wird.