Share via


Verwenden von Utf8JsonWriter in System.Text.Json

In diesem Artikel erfahren Sie, wie Sie den Utf8JsonWriter-Typ zum Erstellen benutzerdefinierter Deserialisierer verwenden.

Mit Utf8JsonWriter lassen sich in UTF-8 codierte JSON-Texte aus gängigen .NET-Typen wie String, Int32 und DateTime schnell mit hohem Durchsatz schreiben. Der Writer ist ein Low-Level-Typ, der zum Erstellen von benutzerdefinierten Serialisierungsmodulen genutzt werden kann. Die JsonSerializer.Serialize-Methode verwendet Utf8JsonWriter verdeckt.

Im folgenden Beispiel wird die Verwendung der Utf8JsonWriter-Klasse veranschaulicht:

var options = new JsonWriterOptions
{
    Indented = true
};

using var stream = new MemoryStream();
using var writer = new Utf8JsonWriter(stream, options);

writer.WriteStartObject();
writer.WriteString("date", DateTimeOffset.UtcNow);
writer.WriteNumber("temp", 42);
writer.WriteEndObject();
writer.Flush();

string json = Encoding.UTF8.GetString(stream.ToArray());
Console.WriteLine(json);
Dim options As JsonWriterOptions = New JsonWriterOptions With {
    .Indented = True
}

Dim stream As MemoryStream = New MemoryStream
Dim writer As Utf8JsonWriter = New Utf8JsonWriter(stream, options)

writer.WriteStartObject()
writer.WriteString("date", DateTimeOffset.UtcNow)
writer.WriteNumber("temp", 42)
writer.WriteEndObject()
writer.Flush()

Dim json As String = Encoding.UTF8.GetString(stream.ToArray())
Console.WriteLine(json)

Schreiben mit UTF-8-Text

Um die bestmögliche Leistung bei Verwendung des Utf8JsonWriter zu erzielen, schreiben Sie JSON-Nutzlasten bereits als UTF-8-codierten Text und nicht als UTF-16-Zeichenfolgen. Verwenden Sie JsonEncodedText, um bekannte Zeichenfolgen-Eigenschaftsnamen sowie -werte als statische Elemente zwischenzuspeichern und vorzucodieren, und übergeben Sie diese dann an den Writer, anstatt UTF-16-Zeichenfolgenliterale zu verwenden. Dies ist schneller als das Zwischenspeichern und Verwenden von UTF-8-Bytearrays.

Diese Vorgehensweise funktioniert auch, wenn Sie benutzerdefiniert escapen müssen. System.Text.Json gestattet Ihnen nicht, während des Schreibens einer Zeichenfolge das Escapen zu deaktivieren. Sie können jedoch Ihren eigenen benutzerdefinierten JavaScriptEncoder als Option an den Writer übergeben oder Ihren eigenen JsonEncodedText erstellen, der Ihren JavascriptEncoder für das Escapen verwendet, und dann den JsonEncodedText anstelle der Zeichenfolge schreiben. Weitere Informationen finden Sie unter Anpassen der Zeichencodierung.

Schreiben von JSON-Rohdaten

In einigen Szenarios müssen Sie möglicherweise JSON-Rohdaten in JSON-Nutzdaten schreiben, die Sie mit Utf8JsonWriter erstellen. Hierfür können Sie Utf8JsonWriter.WriteRawValue verwenden. Dies sind typische Szenarios:

  • Sie verfügen über vorhandene JSON-Nutzdaten, die Sie in neuen JSON-Code einschließen möchten.

  • Sie müssen Werte anders als die Utf8JsonWriter-Standardformatierung formatieren.

    Beispielsweise müssen Sie die Zahlenformatierung anpassen. Standardmäßig lässt System.Text.Json das Dezimalzeichen für ganze Zahlen weg, wobei beispielsweise 1 anstelle von 1.0 geschrieben wird. Der Grund dafür ist, dass das Schreiben weniger Bytes für die Leistung gut ist. Angenommen, der Consumer Ihres JSON-Elements behandelt Zahlen mit Dezimalstellen als Doubles und Zahlen ohne Dezimalstellen als Integer. Sie müssen sicherstellen, dass die Zahlen in einem Array alle als Doubles erkannt werden, indem Sie einen Dezimalpunkt und eine Null für ganze Zahlen verwenden. Das folgende Beispiel zeigt, wie Sie dabei vorgehen müssen:

    using System.Text;
    using System.Text.Json;
    
    namespace WriteRawJson;
    
    public class Program
    {
        public static void Main()
        {
            JsonWriterOptions writerOptions = new() { Indented = true, };
    
            using MemoryStream stream = new();
            using Utf8JsonWriter writer = new(stream, writerOptions);
    
            writer.WriteStartObject();
    
            writer.WriteStartArray("defaultJsonFormatting");
            foreach (double number in new double[] { 50.4, 51 })
            {
                writer.WriteStartObject();
                writer.WritePropertyName("value");
                writer.WriteNumberValue(number);
                writer.WriteEndObject();
            }
            writer.WriteEndArray();
    
            writer.WriteStartArray("customJsonFormatting");
            foreach (double result in new double[] { 50.4, 51 })
            {
                writer.WriteStartObject();
                writer.WritePropertyName("value");
                writer.WriteRawValue(
                    FormatNumberValue(result), skipInputValidation: true);
                writer.WriteEndObject();
            }
            writer.WriteEndArray();
    
            writer.WriteEndObject();
            writer.Flush();
    
            string json = Encoding.UTF8.GetString(stream.ToArray());
            Console.WriteLine(json);
        }
        static string FormatNumberValue(double numberValue)
        {
            return numberValue == Convert.ToInt32(numberValue) ? 
                numberValue.ToString() + ".0" : numberValue.ToString();
        }
    }
    // output:
    //{
    //  "defaultJsonFormatting": [
    //    {
    //      "value": 50.4
    //    },
    //    {
    //      "value": 51
    //    }
    //  ],
    //  "customJsonFormatting": [
    //    {
    //      "value": 50.4
    //    },
    //    {
    //      "value": 51.0
    //    }
    //  ]
    //}
    

Anpassen des Escapens von Zeichen

Die StringEscapeHandling--Einstellung von JsonTextWriter bietet Optionen, um alle Nicht-ASCII-Zeichen oder HTML-Zeichen zu escapen. Standardmäßig escapet Utf8JsonWriter alle Nicht-ASCII- und HTML-Zeichen. Dieses Escapen erfolgt als tief greifende Abwehr aus Gründen des Schutzes. Um eine andere Escaperichtlinie anzugeben, erstellen Sie einen JavaScriptEncoder, und legen Sie JsonWriterOptions.Encoder fest. Weitere Informationen finden Sie unter Anpassen der Zeichencodierung.

Schreiben von Nullwerten

Um Nullwerte mithilfe von Utf8JsonWriter zu schreiben, rufen Sie Folgendes auf:

  • WriteNull, um ein Schlüssel-Wert-Paar mit Null als Wert zu schreiben.
  • WriteNullValue, um Null als Element eines JSON-Arrays zu schreiben.

Wenn eine Zeichenfolge Null ist, entsprechen bei einer Zeichenfolgeneigenschaft WriteString und WriteStringValue den Elementen WriteNull und WriteNullValue.

Schreiben von TimeSpan-, Uri- oder char-Werten

Um Timespan-, Uri- oder char-Werte zu schreiben, formatieren Sie diese als Zeichenfolgen (z. B. durch Aufrufen von ToString()), und rufen Sie WriteStringValue auf.

Siehe auch