System.Text.Json을 사용하여 문자 인코딩을 사용자 지정하는 방법

기본적으로 직렬 변환기는 ASCII가 아닌 문자를 모두 이스케이프합니다. 즉, ASCII가 아닌 문자를 \uxxxx로 바꾸며, 여기서 xxxx는 문자의 유니코드 코드입니다. 예를 들어 다음 JSON의 Summary 속성이 키릴 자모 жарко로 설정된 경우 다음 예제와 같이 WeatherForecast 개체가 직렬화됩니다.

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "\u0436\u0430\u0440\u043A\u043E"
}

언어 문자 세트 직렬화

하나 이상의 언어 문자 세트를 이스케이프하지 않고 직렬화하려면 다음 예제와 같이 System.Text.Encodings.Web.JavaScriptEncoder 인스턴스를 만들 때 유니코드 범위를 지정합니다.

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
Imports System.Text.Encodings.Web
Imports System.Text.Json
Imports System.Text.Unicode
var options1 = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic),
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options1);
options = New JsonSerializerOptions With {
    .Encoder = JavaScriptEncoder.Create(UnicodeRanges.BasicLatin, UnicodeRanges.Cyrillic),
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)

이 코드는 키릴 자모 또는 그리스어 문자를 이스케이프하지 않습니다. Summary 속성이 키릴 자모 жарко로 설정된 경우 다음 예제와 같이 WeatherForecast 개체가 직렬화됩니다.

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "жарко"
}

기본적으로 인코더는 BasicLatin 범위로 초기화됩니다.

모든 언어 세트를 이스케이프하지 않고 직렬화하려면 UnicodeRanges.All을 사용합니다.

특정 문자 직렬화

이스케이프하지 않고 허용하려는 개별 문자를 지정하는 방법도 있습니다. 다음 예제는 жарко의 처음 두 문자만 직렬화합니다.

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
Imports System.Text.Encodings.Web
Imports System.Text.Json
Imports System.Text.Unicode
var encoderSettings = new TextEncoderSettings();
encoderSettings.AllowCharacters('\u0436', '\u0430');
encoderSettings.AllowRange(UnicodeRanges.BasicLatin);
var options2 = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.Create(encoderSettings),
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options2);
Dim encoderSettings As TextEncoderSettings = New TextEncoderSettings
encoderSettings.AllowCharacters(ChrW(&H436), ChrW(&H430))
encoderSettings.AllowRange(UnicodeRanges.BasicLatin)
options = New JsonSerializerOptions With {
    .Encoder = JavaScriptEncoder.Create(encoderSettings),
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)

다음은 이전 코드에서 생성된 JSON 예제입니다.

{
  "Date": "2019-08-01T00:00:00-07:00",
  "TemperatureCelsius": 25,
  "Summary": "жа\u0440\u043A\u043E"
}

차단 목록

앞의 섹션에서는 이스케이프하지 않으려는 코드 요소 또는 범위의 허용 목록을 지정하는 방법을 보여 줍니다. 그러나 허용 목록의 특정 코드 요소를 재정의할 수 있는 전역 및 인코더별 차단 목록이 있습니다. 차단 목록의 코드 지점은 허용 목록에 포함된 경우에도 항상 이스케이프됩니다.

전역 차단 목록

전역 차단 목록에는 프라이빗 사용 문자, 컨트롤 문자, 정의되지 않은 코드 포인트 및 Space_Separator 범주와 같은 특정 유니코드 범주(U+0020 SPACE 제외)가 포함됩니다. 예를 들어 U+3000 IDEOGRAPHIC SPACE는 유니코드 범위 CJK 기호 및 문장 부호(U+3000-U+303F)를 허용 목록으로 지정하더라도 이스케이프됩니다.

전역 차단 목록은 .NET의 모든 릴리스에서 변경된 구현 세부 사항입니다. 전역 차단 목록의 멤버이거나 멤버가 아닌 문자에 대한 종속성은 사용하지 마세요.

인코더별 차단 목록

인코더별 차단된 코드 포인트의 예로는 HTML 인코더에 대한 '<''&', JSON 인코더에 대한 '\', URL 인코더에 대한 '%'가 있습니다. 예를 들어 HTML 인코더는 앰퍼샌드가 BasicLatin 범위에 있고 모든 인코더가 기본적으로 BasicLatin으로 초기화되더라도 항상 앰퍼샌드('&')를 이스케이프합니다.

모든 문자 직렬화

이스케이프를 최소화하려면 다음 예제와 같이 JavaScriptEncoder.UnsafeRelaxedJsonEscaping을 사용합니다.

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Unicode;
Imports System.Text.Encodings.Web
Imports System.Text.Json
Imports System.Text.Unicode
var options3 = new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options3);
options = New JsonSerializerOptions With {
    .Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    .WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)

주의

기본 인코더와 비교할 때, UnsafeRelaxedJsonEscaping 인코더는 문자를 이스케이프하지 않은 상태로 통과할 수 있도록 허용하는 기준이 더 관대합니다.

  • <, >, &'처럼 HTML 구분 문자를 이스케이프하지 않습니다.
  • 문자 세트에 대한 클라이언트와 서버의 내용이 서로 다를 때 발생할 수 있는 XSS 또는 정보 노출 공격에 대한 심층 방어를 추가로 제공하지 않습니다.

클라이언트가 결과 페이로드를 UTF-8로 인코딩된 JSON으로 해석한다는 사실을 알고 있는 경우에만 안전하지 않은 인코더를 사용해야 합니다. 예를 들어 서버에서 응답 헤더 Content-Type: application/json; charset=utf-8을 보내는 경우에 사용할 수 있습니다. 원시 UnsafeRelaxedJsonEscaping 출력을 HTML 페이지나 <script> 요소로 내보내도록 허용하면 절대 안 됩니다.

참고 항목