Aracılığıyla paylaş


Utf8JsonWriter'ı kullanma System.Text.Json

Bu makalede, özel seri hale getiriciler oluşturmak için türünün nasıl kullanılacağı Utf8JsonWriter gösterilmektedir.

Utf8JsonWriter, Int32ve DateTimegibi Stringyaygın .NET türlerinden UTF-8 kodlu JSON metni yazmanın yüksek performanslı bir yoludur. Yazıcı, özel seri hale getiriciler oluşturmak için kullanılabilecek düşük düzeyli bir türdür. JsonSerializer.Serialize yöntemi, kapakların altında kullanırUtf8JsonWriter.

Aşağıdaki örnekte sınıfın nasıl kullanılacağı gösterilmektedir Utf8JsonWriter :

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)

UTF-8 metniyle yazma

kullanırken Utf8JsonWritermümkün olan en iyi performansı elde etmek için JSON yüklerini UTF-16 dizeleri yerine UTF-8 metni olarak zaten kodlanmış olarak yazın. Bilinen dize özellik adlarını ve değerlerini statik olarak önbelleğe almak ve önceden kodlamak ve bunları UTF-16 dize değişmez değerlerini kullanmak yerine yazıcıya geçirmek için kullanın JsonEncodedText . Bu, UTF-8 bayt dizilerini önbelleğe almaktan ve kullanmaktan daha hızlıdır.

Bu yaklaşım, özel kaçış yapmanız gerekiyorsa da çalışır. System.Text.Json dize yazarken kaçışı devre dışı bırakmanıza izin vermez. Ancak, yazıcıya kendi özel JavaScriptEncoder öğenizi bir seçenek olarak geçirebilir veya kaçışı yapmak için öğesini kullanan kendi JsonEncodedText özel öğenizi JavascriptEncoder oluşturabilir ve dize yerine öğesini JsonEncodedText yazabilirsiniz. Daha fazla bilgi için bkz . Karakter kodlamasını özelleştirme.

Ham JSON yazma

Bazı senaryolarda, ile Utf8JsonWriteroluşturduğunuz bir JSON yüküne "ham" JSON yazmak isteyebilirsiniz. Bunu yapmak için kullanabilirsiniz Utf8JsonWriter.WriteRawValue . Tipik senaryolar şunlardır:

  • Yeni JSON içine almak istediğiniz mevcut bir JSON yükünüz var.

  • Değerleri varsayılan Utf8JsonWriter biçimlendirmeden farklı biçimlendirmek istiyorsunuz.

    Örneğin, sayı biçimlendirmesini özelleştirmek isteyebilirsiniz. Varsayılan olarak, System.Text.Json tam sayılar için ondalık ayırıcıyı atlar ve örneğin yerine yazar 11.0. Bunun mantığı, daha az bayt yazmanın performans için iyi olmasıdır. Ancak, JSON'unuzun tüketicisinin sayıları ondalıklarla çift ve ondalık içermeyen sayıları tamsayı olarak değerlendirdiği varsayın. Tam sayılar için ondalık ayırıcı ve sıfır yazarak bir dizideki sayıların tümünün çift olarak tanınmasını sağlamak isteyebilirsiniz. Aşağıdaki örnek bunun nasıl yapılacağını gösterir:

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

Karakter kaçışı özelleştirme

StringEscapeHandling ayarıJsonTextWriter, ASCII olmayan tüm karakterlerden veya HTML karakterlerinden kaçış seçenekleri sunar. Varsayılan olarak, Utf8JsonWriter ASCII olmayan ve HTML olmayan tüm karakterlerden kaçar. Bu kaçış, derinlemesine güvenlik nedeniyle gerçekleştirilir. Farklı bir kaçış ilkesi belirtmek için bir JavaScriptEncoder oluşturun ve ayarlayın JsonWriterOptions.Encoder. Daha fazla bilgi için bkz . Karakter kodlamasını özelleştirme.

Null değerler yazma

kullanarak Utf8JsonWriternull değerler yazmak için çağrısı:

  • WriteNull değeri null olan bir anahtar-değer çifti yazmak için.
  • WriteNullValue bir JSON dizisinin öğesi olarak null yazmak için.

Dize özelliği için, dize null WriteString ise ve WriteStringValue ile WriteNullWriteNullValueeşdeğerdir.

Zaman aralığı, Uri veya karakter değerleri yazma

, veya değerleri yazmak Timespaniçin, bunları dize olarak biçimlendirin (örneğin, çağırarakToString()) ve çağrısı yapınWriteStringValue.charUri

Ayrıca bkz.