Come personalizzare la codifica dei caratteri con System.Text.Json

Per impostazione predefinita, il serializzatore esegue l'escape di tutti i caratteri non ASCII. Ovvero, li sostituisce con \uxxxx dove xxxx è il codice Unicode del carattere. Ad esempio, se la proprietà Summary nel codice JSON seguente è impostata su Cyrillic жарко, l'oggetto WeatherForecast viene serializzato come illustrato in questo esempio:

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

Serializzare set di caratteri di lingua

Per serializzare i set di caratteri di una o più lingue senza escape, specificare intervalli Unicode durante la creazione di un'istanza di System.Text.Encodings.Web.JavaScriptEncoder, come illustrato nell'esempio seguente:

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)

Questo codice non esegue l'escape dei caratteri cirillico o greco. Se la proprietà Summary è impostata su Cyrillic жарко, l'oggetto WeatherForecast viene serializzato come illustrato in questo esempio:

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

Per impostazione predefinita, il codificatore viene inizializzato con l'intervallo BasicLatin.

Per serializzare tutti i set di lingue senza escape, usare UnicodeRanges.All.

Serializzare caratteri specifici

Un'alternativa consiste nel specificare singoli caratteri che si desidera consentire senza che siano preceduti da escape. Nell'esempio seguente vengono serializzati solo i primi due caratteri di жарко:

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)

Ecco un esempio di JSON prodotto dal codice precedente:

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

Elenchi di blocchi

Le sezioni precedenti illustrano come specificare elenchi di punti di codice o intervalli di cui non si vuole eseguire l'escape. Esistono tuttavia elenchi di blocchi globali e specifici del codificatore che possono eseguire l'override di determinati punti di codice nell'elenco elementi consentiti. I punti di codice in un elenco di blocchi vengono sempre preceduti da escape, anche se sono inclusi nell'elenco elementi consentiti.

Elenco globale di blocchi

L'elenco globale di blocchi include elementi come caratteri di utilizzo privato, caratteri di controllo, punti di codice non definiti e determinate categorie Unicode, ad esempio la categoria Space_Separator, escluso U+0020 SPACE. Ad esempio, U+3000 IDEOGRAPHIC SPACE viene eseguito l'escape anche se si specifica l'intervallo Unicode Simboli CJK e punteggiatura (U+3000-U+303F) come elenco elementi consentiti.

L'elenco di blocchi globale è un dettaglio di implementazione modificato in ogni versione di .NET. Non accettare una dipendenza da un carattere membro (o non membro) dell'elenco di blocchi globale.

Elenchi di blocchi specifici del codificatore

Esempi di punti di codice bloccati specifici del codificatore includono '<' e '&' per il codificatore HTML, '\' per il codificatore JSONe '%' per il codificatore URL. Ad esempio, il codificatore HTML esegue sempre l'escape di e commerciale ('&'), anche se l'e commerciale si trova nell'intervallo BasicLatin e tutti i codificatori vengono inizializzati con BasicLatin per impostazione predefinita.

Serializzare tutti i caratteri

Per ridurre al minimo l'escape, è possibile usare JavaScriptEncoder.UnsafeRelaxedJsonEscaping, come illustrato nell'esempio seguente:

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)

Attenzione

Rispetto al codificatore predefinito, il codificatore UnsafeRelaxedJsonEscaping è più permissivo per consentire il passaggio dei caratteri senza caratteri di escape:

  • Non esegue l'escape dei caratteri sensibili a HTML, ad esempio <, >, &e '.
  • Non offre protezioni aggiuntive di difesa avanzata da attacchi XSS o di divulgazione di informazioni, ad esempio quelli che potrebbero risultare dal client e dal server in disaccordo sul charset.

Usare il codificatore unsafe solo quando è noto che il client interpreterà il payload risultante come JSON con codifica UTF-8. Ad esempio, è possibile usarlo se il server invia l'intestazione della risposta Content-Type: application/json; charset=utf-8. Non consentire mai di generare l'output UnsafeRelaxedJsonEscaping non elaborato in una pagina HTML o in un elemento <script>.

Vedi anche