dotnet core System.Text.Json unescape string unicode

Sep 18 2019

Menggunakan JsonSerializer.Serialize(obj)akan menghasilkan string yang lolos, tetapi saya ingin versi yang tidak lolos. Sebagai contoh:

using System;
using System.Text.Json;

public class Program
{
    public static void Main()
    {
        var a = new A{Name = "你好"};
        var s = JsonSerializer.Serialize(a);
        Console.WriteLine(s);
    }
}

class A {
    public string Name {get; set;}
}

akan menghasilkan string {"Name":"\u4F60\u597D"}tapi saya mau{"Name":"你好"}

Saya membuat cuplikan kode di https://dotnetfiddle.net/w73vnO
Tolong bantu saya.

Jawaban

28 rcs Sep 19 2019 at 03:38

Anda perlu menyetel opsi JsonSerializer untuk tidak menyandikan string tersebut.

JsonSerializerOptions jso = new JsonSerializerOptions();
jso.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;

Kemudian Anda memberikan opsi ini saat memanggil Serializemetode Anda .

var s = JsonSerializer.Serialize(a, jso);        

Kode lengkap:

JsonSerializerOptions jso = new JsonSerializerOptions();
jso.Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping;

var a = new A { Name = "你好" };
var s = JsonSerializer.Serialize(a, jso);        
Console.WriteLine(s);

Hasil:

Jika Anda perlu mencetak hasilnya di konsol, Anda mungkin perlu menginstal bahasa tambahan. Silakan lihat di sini .

18 ahsonkhan Dec 10 2019 at 04:24

Untuk mengubah perilaku pelolosan, JsonSerializerAnda dapat meneruskan kustom JavascriptEncoderke JsonSerializerdengan menyetel Encoderproperti di JsonSerializerOptions.

https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializeroptions.encoder?view=netcore-3.0#System_Text_Json_JsonSerializerOptions_Encoder

Perilaku default dirancang dengan mempertimbangkan keamanan dan JsonSerializerpelarian yang berlebihan untuk pertahanan yang lebih mendalam.

Jika semua yang Anda cari adalah keluar dari karakter "alfanumerik" tertentu dari bahasa non-latin tertentu, saya sarankan Anda membuat JavascriptEncodermenggunakan Createmetode pabrik daripada menggunakan UnsafeRelaxedJsonEscapingencoder.

JsonSerializerOptions options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.CjkUnifiedIdeographs)
};

var a = new A { Name = "你好" };
var s = JsonSerializer.Serialize(a, options);
Console.WriteLine(s);

Melakukannya untuk menjaga keamanan tertentu, misalnya, karakter sensitif HTML akan terus lolos.

Saya akan berhati-hati agar tidak menggunakan System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping sembarangan karena ia melakukan pelarian minimal (itulah sebabnya ia memiliki "tidak aman" pada namanya). Jika JSON yang Anda buat ditulis ke file berenkode UTF-8 pada disk atau jika bagiannya dari permintaan web yang secara eksplisit menyetel charset ke utf-8 (dan tidak akan berpotensi disematkan dalam komponen HTML sebagaimana adanya), maka mungkin OK untuk menggunakan ini.

Lihat bagian komentar dalam dokumen API: https://docs.microsoft.com/en-us/dotnet/api/system.text.encodings.web.javascriptencoder.unsaferelaxedjsonescaping?view=netcore-3.0#remarks

Anda juga dapat mempertimbangkan untuk menentukan UnicodeRanges.Alljika Anda mengharapkan / membutuhkan semua bahasa tetap tidak di-escape. Ini masih lolos dari karakter ASCII tertentu yang rentan terhadap kerentanan keamanan.

JsonSerializerOptions options = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.All)
};

Untuk informasi lebih lanjut dan contoh kode, lihat : https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-how-to?view=netcore-3.0#customize-character-encoding

Lihat Catatan Perhatian