Sdílet prostřednictvím


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, 11.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é