Share via


Så här anpassar du teckenkodning med System.Text.Json

Som standard undflyr serialiseraren alla icke-ASCII-tecken. Det vill: den ersätter dem med \uxxxx var xxxx är Unicode-koden för tecknet. Om Summary egenskapen i följande JSON till exempel är inställd på kyrillisk жаркоWeatherForecast serialiseras objektet enligt det här exemplet:

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

Serialisera språkteckenuppsättningar

Om du vill serialisera teckenuppsättningarna för ett eller flera språk utan att komma ifrån anger du Unicode-intervall när du skapar en instans av System.Text.Encodings.Web.JavaScriptEncoder, enligt följande exempel:

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)

Den här koden undflyr inte kyrilliska eller grekiska tecken. Om egenskapen är inställd på Summary kyrillisk жаркоWeatherForecast serialiseras objektet enligt följande exempel:

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

Kodaren initieras som standard med BasicLatin intervallet.

Om du vill serialisera alla språkuppsättningar utan att komma ifrån använder du UnicodeRanges.All.

Serialisera specifika tecken

Ett alternativ är att ange enskilda tecken som du vill tillåta utan att bli undantagna. I följande exempel serialiseras endast de två första tecknen i жарко:

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)

Här är ett exempel på JSON som skapats av föregående kod:

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

Blockera listor

I föregående avsnitt visas hur du anger tillåtna listor över kodpunkter eller intervall som du inte vill ska vara undantagna. Det finns dock globala och kodarspecifika blocklistor som kan åsidosätta vissa kodpunkter i listan över tillåtna. Kodpunkter i en blockeringslista är alltid undantagna, även om de ingår i listan över tillåtna.

Global blockeringslista

Den globala blocklistan innehåller saker som privata tecken, kontrolltecken, odefinierade kodpunkter och vissa Unicode-kategorier, till exempel kategorin Space_Separator, exklusive U+0020 SPACE. Är till exempel U+3000 IDEOGRAPHIC SPACE undantagen även om du anger CJK-symboler och skiljetecken (U+3000-U+303F) som din tillåtna lista.

Den globala blocklistan är en implementeringsinformation som har ändrats i varje version av .NET. Var inte beroende av att ett tecken är medlem i (eller inte är medlem i) listan över globala block.

Kodarspecifika blocklistor

Exempel på kodarspecifika blockerade kodpunkter är '<' html-kodaren '&', '\' JSON-kodaren och '%'URL-kodaren. HTML-kodaren undflyr till exempel alltid et-tecken ('&'), även om et-et är i BasicLatin intervallet och alla kodare initieras med BasicLatin som standard.

Serialisera alla tecken

För att minimera undflyende kan du använda JavaScriptEncoder.UnsafeRelaxedJsonEscaping, som du ser i följande exempel:

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)

Varning

Jämfört med standardkodaren UnsafeRelaxedJsonEscaping är kodaren mer tillåtande när det gäller att tillåta tecken att passera utan kapslade tecken:

  • Den undflyr inte HTML-känsliga tecken som <, >, &och '.
  • Det erbjuder inte några ytterligare skydd på djupet mot XSS- eller informationsutlämnandeattacker, till exempel sådana som kan bero på att klienten och servern inte håller med om teckenuppsättningen.

Använd endast den osäkra kodaren när det är känt att klienten tolkar den resulterande nyttolasten som UTF-8-kodad JSON. Du kan till exempel använda den om servern skickar svarshuvudet Content-Type: application/json; charset=utf-8. Tillåt aldrig att råutdata UnsafeRelaxedJsonEscaping skickas till en HTML-sida eller ett <script> element.

Se även