Jak používat Utf8JsonWriter v System.Text.Json

Tento článek ukazuje, jak použít Utf8JsonWriter typ pro vytváření vlastních serializátorů.

Utf8JsonWriter je vysoce výkonný způsob, jak psát kódovaný text JSON UTF-8 z běžných typů .NET, jako je String, Int32a DateTime. Zapisovač je typ nízké úrovně, který lze použít k sestavení vlastních serializátorů. Metoda JsonSerializer.Serialize se používá Utf8JsonWriter pod kryty.

Následující příklad ukazuje, jak používat Utf8JsonWriter třídu:

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)

Zápis s textem UTF-8

Pokud chcete dosáhnout nejlepšího možného výkonu Utf8JsonWriterpři použití , zapište datové části JSON, které jsou již kódovány jako text UTF-8, nikoli jako řetězce UTF-16. Slouží JsonEncodedText k ukládání a předkódování názvů známých řetězcových vlastností a hodnot jako statických hodnot a jejich předávání do zapisovače místo použití řetězcových literálů UTF-16. To je rychlejší než ukládání do mezipaměti a použití bajtů UTF-8.

Tento přístup funguje také v případě, že potřebujete provádět vlastní zapouzdření. System.Text.Json neumožňuje zakázat escaping při psaní řetězce. Můžete však předat vlastní jako JavaScriptEncoder možnost zápisu nebo vytvořit vlastní JsonEncodedText , který používá k JavascriptEncoder tomu, aby se zapouzdření, a pak místo řetězce zapsat JsonEncodedText . Další informace naleznete v tématu Přizpůsobení kódování znaků.

Zápis nezpracovaných JSON

V některých scénářích můžete chtít napsat "nezpracovaný" JSON do datové části JSON, kterou vytváříte.Utf8JsonWriter Můžete to udělat.Utf8JsonWriter.WriteRawValue Tady jsou typické scénáře:

  • Máte existující datovou část JSON, kterou chcete uzavřít do nového formátu JSON.

  • Hodnoty chcete formátovat jinak než výchozí Utf8JsonWriter formátování.

    Můžete například chtít přizpůsobit formátování čísel. Ve výchozím nastavení System.Text.Json vynechá desetinnou čárku pro celá čísla, 1 1.0ale ne například. Důvodem je, že psaní menšího počtu bajtů je dobré pro výkon. Předpokládejme ale, že příjemce kódu JSON považuje čísla za dvojité a čísla bez desetinných míst jako celá čísla. Možná budete chtít zajistit, aby se všechna čísla v matici rozpoznala jako dvojitá, a to napsáním desetinné čárky a nuly pro celá čísla. Následující příklad ukazuje, jak to udělat:

    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
    //    }
    //  ]
    //}
    

Přizpůsobení znakového uvozování

Nastavení JsonTextWriter StringEscapeHandling nabízí možnosti pro řídicí znaky všech znaků, které nejsou ASCII nebo znaky HTML. Ve výchozím nastavení Utf8JsonWriter uchycuje všechny znaky, které nejsou ASCII a HTML. Tento únik se provádí z bezpečnostních důvodů hloubkové ochrany. Chcete-li zadat jinou zásadu escapingu, vytvořte JavaScriptEncoder a nastavte JsonWriterOptions.Encoder. Další informace naleznete v tématu Přizpůsobení kódování znaků.

Zápis hodnot null

K zápisu hodnot null pomocí Utf8JsonWritervolání:

  • WriteNull pro zápis páru klíč-hodnota s hodnotou null jako hodnotou.
  • WriteNullValue k zápisu hodnoty null jako elementu pole JSON.

Pro řetězcovou vlastnost, pokud je řetězec null WriteString a WriteStringValue jsou ekvivalentní k WriteNull a WriteNullValue.

Hodnoty časového rozsahu, identifikátoru URI nebo znaku

Pokud chcete napsat , Urinebo hodnoty, naformátujte Timespanje jako řetězce (voláním ToString(), například) a voláním WriteStringValuechar .

Viz také