MYMONDAY.ai
서비스스튜디오도구데이터·포맷73CSS 생성기19색상·이미지10인코딩·보안10웹·SEO11개발·데브옵스10파일·내보내기18계산기6가이드

JSON to C# 클래스 변환기

JSON 객체나 배열을 붙여 넣으면 PascalCase 프로퍼티, JsonPropertyName 특성, nullable 표기가 있는 System.Text.Json용 C# 클래스를 만듭니다.

  • 브라우저에서 처리
  • 가입 없음
  • 무료

도구 작업 공간

예제

옵션

JSON 입력

27줄435byte

결과

⌘/Ctrl + Enter로 복사
결과 · Payload.cs
#nullable enable
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

public class Payload
{
    [JsonPropertyName("id")]
    public int Id { get; set; }
    [JsonPropertyName("status")]
    public string Status { get; set; } = string.Empty;
    [JsonPropertyName("customer")]
    public PayloadCustomer Customer { get; set; } = new();
    [JsonPropertyName("items")]
    public List<PayloadItem> Items { get; set; } = new();
    [JsonPropertyName("total")]
    public double Total { get; set; }
    [JsonPropertyName("shipped_at")]
    public string ShippedAt { get; set; } = string.Empty;
    [JsonPropertyName("tracking")]
    public JsonElement? Tracking { get; set; }
}

public class PayloadCustomer
{
    [JsonPropertyName("id")]
    public int Id { get; set; }
    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;
    [JsonPropertyName("email")]
    public string Email { get; set; } = string.Empty;
    [JsonPropertyName("vip")]
    public bool Vip { get; set; }
}

public class PayloadItem
{
    [JsonPropertyName("sku")]
    public string Sku { get; set; } = string.Empty;
    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;
    [JsonPropertyName("qty")]
    public int Qty { get; set; }
    [JsonPropertyName("price")]
    public double Price { get; set; }
}
타입3
크기1.3kB

이 JSON to C# 변환기는 샘플 JSON 값을 { get; set; } 프로퍼티와 System.Text.Json.Serialization의 [JsonPropertyName("key")] 특성이 있는 일반 클래스로 바꿉니다. 중첩 객체는 별도 클래스가 되고, 키는 PascalCase 프로퍼티가 되며, 파일은 #nullable enable로 시작합니다. null이 아닌 문자열, 리스트, 중첩 객체에는 초기값(= string.Empty;, = new();)이 붙어서 CS8618 경고 없이 컴파일됩니다.

배열의 모든 요소는 키의 합집합을 프로퍼티로 가진 클래스 하나로 병합됩니다. 일부 요소에 없거나 일부에서 null인 키는 int?, string? 같은 nullable 프로퍼티가 됩니다. 한 키에서 값의 타입이 서로 다르면 JsonElement입니다. 루트는 객체 또는 배열이며, 배열 루트는 주석과 요소 클래스가 출력됩니다.

JsonSerializer.Deserialize<Payload>(json)이 응답을 읽는 일반적인 방법인 .NET 6 이상을 대상으로 합니다. 변환은 브라우저에서 이루어지고 업로드되지 않으며, 입력 한도는 20 MiB입니다. 페이지에는 루트 타입 이름과 네임스페이스 옵션이 있고, 내려받는 파일은 루트 이름을 따라 기본값 Payload.cs입니다.

사용 방법

  1. JSON 객체 또는 배열 붙여 넣기

    페이로드를 붙여 넣거나 예제(API 응답, 중첩 배열, 엣지 케이스) 중 하나를 불러옵니다. 최상위가 문자열·숫자·불리언·null 단독 값이면 오류가 표시됩니다.

  2. 루트 타입 이름과 네임스페이스 설정

    루트 클래스 이름(기본 Payload)을 입력합니다. PascalCase로 변환되고, 숫자로 시작하면 Model 접두사가 붙습니다. 네임스페이스를 입력하면 파일 범위 namespace 줄이 추가되며 기본값은 비어 있습니다.

  3. 클래스 읽기

    머리에는 #nullable enable과 출력에 필요한 using 줄만 나오고, 루트 클래스가 먼저, 중첩 클래스가 처음 만난 순서대로 이어집니다. 프로퍼티 이름이 키와 같지 않은 한 각 프로퍼티에 JsonPropertyName이 붙습니다.

  4. 타입 점검

    int, long, double, JsonElement를 하나씩 확인합니다. 이 타입들은 샘플 값에서 나온 것이어서 샘플에서는 작은 필드도 운영에서는 더 클 수 있습니다.

  5. 복사하거나 .cs로 저장

    코드를 복사하거나 루트 클래스 이름을 딴 파일(기본 Payload.cs)로 내려받아 프로젝트에 추가합니다.

작동 원리

JSON과 C# 타입 대응

C#은 int, long, double을 구분합니다. -2147483648부터 2147483647까지의 정수 표기는 int, 그 범위 밖이면서 절댓값 2^63 미만이면 long, 절댓값 2^63 이상이면 double입니다. 10.0이나 1e3 같은 소수점·지수 표기는 값이 정수여도 double입니다. 같은 위치의 값을 병합하면 [1, 2.5]는 List<double>이 됩니다.

JSON 값C# 타입초기값 / 비고
문자열string= string.Empty;
true / falsebool
-2147483648부터 2147483647까지의 정수 표기int
그보다 크고 2^63 미만인 정수 표기long샘플 값으로 결정
소수가 있는 숫자double
모든 샘플에서 nullJsonElement?using System.Text.Json 추가
일부 요소에서 null이거나 없음T?예: int?, string?, 초기값 없음
객체public class Namenull이 아닐 때 = new();
배열List<T>= new(); using System.Collections.Generic 추가
빈 배열 또는 혼합 형태List<JsonElement> / JsonElement[1, "a"]는 List<JsonElement>

이름과 특성

프로퍼티와 클래스 이름은 camelCase 경계와 영문·숫자가 아닌 문자에서 단어를 나눠 첫 글자를 대문자로 만듭니다. first_name은 FirstName, user-agent는 UserAgent입니다. 숫자로 시작하면 프로퍼티는 Field, 클래스는 Model 접두사가 붙어 2fa는 Field2fa가 됩니다. 같은 이름이 되는 키는 2부터 번호가 붙습니다.

[JsonPropertyName]은 C# 이름이 키와 다르면, 대소문자만 달라도 붙습니다. id가 Id가 되므로 대부분의 프로퍼티에 특성이 붙는데, PropertyNameCaseInsensitive를 설정하지 않으면 System.Text.Json의 기본 매칭이 대소문자를 구분하기 때문입니다. 소속 클래스와 이름이 같아지는 프로퍼티는 C#이 금지하므로(CS0542) Value 접미사가 붙습니다.

[JsonPropertyName("user-agent")]
public string UserAgent { get; set; } = string.Empty;
public int? Qty { get; set; }

System.Text.Json으로 역직렬화

var payload = JsonSerializer.Deserialize<Payload>(json);이 클래스를 채웁니다. JsonElement 프로퍼티는 임의의 JSON을 보관하며 GetString(), GetInt64(), EnumerateObject()로 읽습니다.

클래스는 record나 init이 아닌 set 가능한 프로퍼티를 써서 오래된 도구와도 호환됩니다. = new(); 초기값에는 C# 9, 파일 범위 네임스페이스에는 C# 10이 필요합니다. 생성된 파일에는 required 한정자가 붙지 않습니다.

실제 예시

List<string>이 있는 중첩 객체
입력
{"id":42,"user":{"name":"Ada","active":true},"roles":["admin","editor"]}
출력
#nullable enable
using System.Collections.Generic;
using System.Text.Json.Serialization;

public class Payload
{
    [JsonPropertyName("id")]
    public int Id { get; set; }
    [JsonPropertyName("user")]
    public PayloadUser User { get; set; } = new();
    [JsonPropertyName("roles")]
    public List<string> Roles { get; set; } = new();
}

public class PayloadUser
{
    [JsonPropertyName("name")]
    public string Name { get; set; } = string.Empty;
    [JsonPropertyName("active")]
    public bool Active { get; set; }
}

Id가 id와 대소문자가 달라서 모든 프로퍼티에 JsonPropertyName 특성이 붙습니다. 문자열, 리스트, 중첩 클래스에는 초기값이 붙고 int와 bool에는 필요 없습니다.

int, long, double
입력
{"small":-5,"big":2147483648,"price":19.5,"ids":[1,3000000000],"names":["a",null],"deleted_at":null}
출력
#nullable enable
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

public class Payload
{
    [JsonPropertyName("small")]
    public int Small { get; set; }
    [JsonPropertyName("big")]
    public long Big { get; set; }
    [JsonPropertyName("price")]
    public double Price { get; set; }
    [JsonPropertyName("ids")]
    public List<long> Ids { get; set; } = new();
    [JsonPropertyName("names")]
    public List<string?> Names { get; set; } = new();
    [JsonPropertyName("deleted_at")]
    public JsonElement? DeletedAt { get; set; }
}

int 범위 안의 정수는 int, 밖은 long입니다. [1, 3000000000]은 List<long>으로 합쳐지고, 문자열 사이의 null은 List<string?>, 항상 null인 deleted_at은 JsonElement?입니다.

PascalCase 이름과 충돌
입력
{"user_id":1,"userId":2,"2fa":true,"class":"A","user-agent":"curl"}
출력
#nullable enable
using System.Text.Json.Serialization;

public class Payload
{
    [JsonPropertyName("user_id")]
    public int UserId { get; set; }
    [JsonPropertyName("userId")]
    public int UserId2 { get; set; }
    [JsonPropertyName("2fa")]
    public bool Field2fa { get; set; }
    [JsonPropertyName("class")]
    public string Class { get; set; } = string.Empty;
    [JsonPropertyName("user-agent")]
    public string UserAgent { get; set; } = string.Empty;
}

프로퍼티는 PascalCase입니다. UserId로 매핑되는 두 번째 프로퍼티에는 2가 붙고, 숫자로 시작하면 Field 접두사가 붙습니다.

클래스와 이름이 같은 프로퍼티
입력
{"payload":1}
출력
#nullable enable
using System.Text.Json.Serialization;

public class Payload
{
    [JsonPropertyName("payload")]
    public int PayloadValue { get; set; }
}

payload 키는 class Payload 안에 Payload 프로퍼티를 만드는데, C#은 이를 CS0542로 거부합니다. 변환기가 Value를 붙이고 JsonPropertyName은 여전히 payload 키를 가리킵니다.

키가 서로 다른 객체 배열
입력
{"customers":[{"id":1,"name":"Ada","tags":["a"]},{"id":2,"vip":true}]}
출력
#nullable enable
using System.Collections.Generic;
using System.Text.Json.Serialization;

public class Payload
{
    [JsonPropertyName("customers")]
    public List<PayloadCustomer> Customers { get; set; } = new();
}

public class PayloadCustomer
{
    [JsonPropertyName("id")]
    public int Id { get; set; }
    [JsonPropertyName("name")]
    public string? Name { get; set; }
    [JsonPropertyName("tags")]
    public List<string>? Tags { get; set; }
    [JsonPropertyName("vip")]
    public bool? Vip { get; set; }
}

두 고객을 모두 읽습니다. name, tags, vip는 한 요소에만 있어 nullable(string?, List<string>?, bool?)이 되고, id는 둘 다 있어 일반 int입니다.

네임스페이스가 있는 배열 루트
입력
[{"sku":"A1"},{"sku":"B2","qty":3}]
출력
#nullable enable
using System.Text.Json.Serialization;

namespace Shop.Models;

// The root JSON value is List<CatalogItem>

public class CatalogItem
{
    [JsonPropertyName("sku")]
    public string Sku { get; set; } = string.Empty;
    [JsonPropertyName("qty")]
    public int? Qty { get; set; }
}

옵션: 루트 타입 이름 Catalog, 네임스페이스 Shop.Models. 배열 루트에는 자체 클래스가 없어서 주석과 요소 클래스 CatalogItem이 출력되고, 선택 필드 qty는 int?입니다.

자주 하는 실수

  • 샘플 하나로는 항상 있는 필드인지 알 수 없습니다

    붙여 넣은 요소 중 키가 없거나 null인 것이 있을 때만 nullable이 됩니다. 레코드가 하나뿐이면 누락된 값 타입 키는 0 또는 false가 되고, 생성된 초기값 때문에 문자열은 빈 문자열, 리스트는 빈 리스트, 중첩 객체는 새 객체로 남습니다. 값이 빠진 레코드도 붙여 넣으세요.

  • int와 long은 샘플로 정해집니다

    샘플에서 5인 필드는 int이지만 운영에서는 3000000000이 올 수 있고 그러면 역직렬화에서 예외가 납니다. 샘플이 작아도 ID와 카운터에는 long을 쓰세요. 타입 추론에서 2^53을 넘는 값을 JavaScript 숫자로 바꾸면 반올림될 수 있으므로 정확한 ID에는 string이나 decimal을 쓰세요.

  • null뿐인 필드는 JsonElement?가 됩니다

    붙여 넣은 모든 레코드에서 null인 키는 타입 정보가 없어 JsonElement?입니다. 실제 타입을 알게 되면 DateTime? 같은 구체 nullable 타입으로 바꾸세요.

  • 소수점·지수 표기는 double이 됩니다

    19.0과 1e3은 값이 정수여도 double이 됩니다. 19 같은 정수 표기는 int로 남으므로 API가 실제로 보내는 숫자 표기를 샘플에 넣으세요.

  • 섞인 형태는 JsonElement가 됩니다

    한 레코드에서는 숫자, 다른 레코드에서는 문자열인 키는 JsonElement가 됩니다. 곳곳에서 직접 읽기보다 API를 정리하거나 JsonConverter를 작성하세요.

  • 명명 정책과 특성이 겹칠 수 있습니다

    대부분의 프로퍼티에 JsonPropertyName이 있으므로 PropertyNamingPolicy = JsonNamingPolicy.CamelCase를 설정해도 그 프로퍼티에는 영향이 없습니다. 특성이 항상 정책보다 우선하니 프로퍼티 이름을 바꿀 때는 특성도 함께 고치세요.

자주 묻는 질문

Newtonsoft.Json을 쓰나요, System.Text.Json을 쓰나요?

System.Text.Json이며 특성은 [JsonPropertyName]입니다. Newtonsoft.Json을 쓰려면 [JsonProperty]로 바꾸세요.

배열의 모든 요소를 읽나요?

네. 모든 요소의 객체를 키의 합집합을 가진 클래스 하나로 병합합니다. 일부 요소에 없는 키는 nullable이 되고, 한 키에서 값의 타입이 다르면 JsonElement가 됩니다.

대부분의 프로퍼티에 JsonPropertyName이 붙는 이유는 무엇인가요?

C# 프로퍼티는 PascalCase이고 JSON 키는 대개 그렇지 않으며 System.Text.Json은 기본적으로 대소문자를 구분하기 때문입니다. C# 이름이 키와 다르면 대소문자만 달라도 특성이 붙습니다.

int, long, double은 어떻게 고르나요?

-2147483648부터 2147483647까지의 정수 표기는 int, 그 범위 밖이면서 절댓값 2^63 미만이면 long, 절댓값 2^63 이상이면 double입니다. 소수점·지수 표기나 같은 위치의 소수 값도 double로 만듭니다.

프로퍼티 이름 끝에 Value가 붙는 이유는 무엇인가요?

멤버는 소속 클래스와 같은 이름을 가질 수 없어서, Payload 클래스 안의 payload 키는 [JsonPropertyName("payload")]와 함께 PayloadValue가 됩니다.

네임스페이스와 루트 클래스 이름을 지정할 수 있나요?

네. 루트 타입 이름은 PascalCase로 변환되어 루트 클래스와 파일 이름이 됩니다. 네임스페이스는 파일 범위 namespace Name; 줄을 추가하며 C# 10이 필요합니다.

JSON이 서버로 전송되나요?

아니요. 변환은 브라우저에서 이루어지며 입력 한도는 20 MiB입니다.

마지막 업데이트: