100% ローカル — データがブラウザの外に出ることはありません

JSONをC#に変換|System.Text.Jsonが読めるrecordに

JSONのサンプルをC#のrecordまたはクラスに変換します。名前を変えたプロパティには JsonPropertyName 属性が付くので、逆シリアル化でもキーを見失いません。

高速 プライベート Cookieゼロ
スタイル

JSON 入力

C# 出力

このツールの動作

JSON の標本が C# のレコードになります。オブジェクト一つにつき一つです。

{ "id": 1, "firstName": "Ada", "address": { "city": "Paris" } }
using System.Text.Json.Serialization;

public record Root(
    [property: JsonPropertyName("id")] long Id,
    [property: JsonPropertyName("firstName")] string FirstName,
    [property: JsonPropertyName("address")] Address Address
);

public record Address(
    [property: JsonPropertyName("city")] string City
);

位置指定レコードには C# 9 が要ります。using は、属性が現れるときにだけ現れます。

属性の付け先が効く

C# のプロパティ名は PascalCase です。firstName は FirstName に、content-type は ContentType になります。System.Text.Json が大文字小文字を無視して照合するのは、そう頼んだときだけで、ハイフンをまたぐことは決してありません。だから鍵は属性で固定します。

property: の接頭辞は、間違えやすいところです。位置指定レコードでは、引数はプロパティではありません。付け先の無い属性は構築子の引数に留まり、直列化器の目には入りません。付け先を書けば、読まれる場所に届きます。

型

  • 整数は long、小数は double になります。どちらも 32 ビットの既定より広く取ります。JSON の数値はそこに収まると約束していないからです。
  • null と型の分からない値は object? になります。null 許容参照型を有効にしていることが前提です(.NET 6 以降は既定で有効です)。
  • 配列は List<T> になります。型の混ざった配列は List<object> に、整数と小数だけが混ざっている場合は List<double> が両方を覆います。
  • 根が数値や文字列なら拒みます。C# に全体で使える型別名は無く、42 がなるものがないからです。オブジェクトの配列からは要素のレコードが得られます。List<Root> に結びつけるのはそれです。

標本が言えないこと

object? のほかに null を許すプロパティはなく、既定値を持つものもありません。文書がそれぞれに値を持っていたからです。どの鍵が本当に必須かが分かったら、required と init を足す値打ちがあります。標本が言えるのは、たまたまそこにあった鍵がどれか、だけです。

プライバシー

すべての処理はブラウザ内のJavaScriptだけで完結します。データがアップロードされることはないため、機密情報でも安心して利用でき、オフラインでも動作します。

よくある質問

なぜ `[JsonPropertyName(...)]` ではなく `[property: JsonPropertyName(...)]` なのですか。
位置指定レコードの引数は、まだプロパティではないからです。`property:` の指定が無いと、属性は構築子の引数に付きます。直列化器はそこを決して見ませんし、コンパイラも警告します。指定があれば、生成されたプロパティへ移ります。`System.Text.Json` が読むのはそちらです。
Newtonsoft.Json を使っています。何を変えますか。
属性とその using です。`Newtonsoft.Json` とともに `[property: JsonProperty("content-type")]` と書きます。ほかは変わりません。プロパティ名も型もレコードの形も同じです。Newtonsoft は既定で大文字小文字を区別せずに照合するので、`camelCase` の鍵なら属性なしでも通ることが多いです。
レコードとクラス、どちらがよいですか。
既定はレコードです。値としての等価、`with` 式、そして生成時にすべての項目を明示させる構築子が得られます。クラスの選択肢では、代入できるプロパティになります。古いコードや、代入でオブジェクトを組み立てる枠組みが求めるのはそちらです。読み取る型はどちらでも同じです。

関連ツール