Xamarin.FormsでSystem.Text.JSONでJSONファイルからデシリアライズするときのメモ
https://codeburst.io/working-with-json-in-net-core-3-2fd1236126c1codeburst.io
ここでは予めデシリアライズ先の型を用意して,Embedded resourceに指定したJSONファイルから読み込んだデータをデシリアライズする手順を示す.
System.Text.Jsonをインストール
Nugetからインストールする.
Jsonデータからクラスを生成する.
既存のWebAPIからデータをJSON形式で受け取る場合,そのJSONデータからデシリアライズ先のクラスを生成することができる.
WebAPIが返すJSONデータをまるっとコピーして,Visual StudioのメニューからEdito -> Paste Special -> Paste JSON as classes
を選択すると,クラスが生成される.
JSON:
[ { "id": 1, "first_name": "Danell", "last_name": "Hawksworth", "email": "dhawksworth0@upenn.edu", "gender": "Female", "ip_address": "81.48.89.94" }, { "id": 2, "first_name": "Cob", "last_name": "Chapiro", "email": "cchapiro1@posterous.com", "gender": "Male", "ip_address": "122.16.10.192" }, { "id": 3, "first_name": "Helli", "last_name": "Fairholme", "email": "hfairholme2@springer.com", "gender": "Female", "ip_address": "124.131.30.108" } ]
↓
生成されたC#のクラス
public class Rootobject { public Class1[] Property1 { get; set; } } public class Class1 { public int id { get; set; } public string first_name { get; set; } public string last_name { get; set; } public string email { get; set; } public string gender { get; set; } public string ip_address { get; set; } }
デシリアライズにこれをそのまま使っても良いが,Class1などになっているので適切な名前にに変更しておくとよい.
また,プロパティ名はJSONデータで使用されている名前がそのまま使われるので,C#のコーディング作法とは異なる場合がほとんどである.
プロパティ名を変更しただけでは,JSONデータとC#クラスの間で対応付けができなくなってしまうので,JsonPropertyName
属性を使うことで,これを解決する.
public class Rootobject { public Person[] People { get; set; } } public class Person { [JsonPropertyName("id")] public int Id { get; set; } [JsonPropertyName("first_name")] public string FirstName { get; set; } [JsonPropertyName("last_name")] public string LastName { get; set; } [JsonPropertyName("email")] public string Email { get; set; } [JsonPropertyName("gender")] public string Gender { get; set; } [JsonPropertyName("ip_address")] public string IpAddress { get; set; } }
このように各プロパティにJsonPropertyName
属性でJSONデータにおける名前と,それに対応するC#のプロパティを明示する.
シリアライズする際に,日本語が文字コードになってしまうのですが,これについてはJsonSerializerOptions
を使います.
var options = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.Create(UnicodeRanges.All),
};
デシリアライズ
ファイルから読み込む場合はこんな感じ.この例は,プロジェクトにEmbedded resourceとして追加したJSONファイルを読み込んでデシリアライズするとき.
var assembly = Assembly.GetExecutingAssembly(); using var stream = assembly.GetManifestResourceStream("XFCollectionViewGrouping.Data.PeopleData.json"); var people = await System.Text.Json.JsonSerializer.DeserializeAsync<Person[]>(stream);
コメントつきのJSONをデシリアライズする場合は,以下のようにします.
JsonSerializerOptionsで設定できること
個人的注目 | プロパティ | 説明 |
---|---|---|
★ | AllowTrailingCommas | 逆シリアル化される JSON ペイロード内でオブジェクトまたは配列の JSON 値の一覧の終わりにある余分なコンマが許可 (および無視) されるかどうかを示す値を取得または設定します。 |
Converters | 登録されたユーザー定義のコンバーターの一覧を取得します。 | |
DefaultBufferSize | 一時バッファーの作成時に使用する、既定のバッファー サイズ (バイト単位) を取得または設定します。 | |
DictionaryKeyPolicy | IDictionary キーの名前を、camel 形式などの別の形式に変換するために使用されるポリシーを取得または設定します。 | |
★ | Encoder | 文字列をエスケープするときに使用するエンコーダーを取得または設定します。既定のエンコーダーを使用する場合は null を設定します。 |
★ | IgnoreNullValues | シリアル化および逆シリアル化の間に null 値を無視するかどうかを決定する値を取得または設定します。 既定値は false です。 |
IgnoreReadOnlyProperties | シリアル化中に読み取り専用プロパティを無視するかどうかを決定する値を取得します。 既定値は false です。 | |
MaxDepth | JSON をシリアル化または逆シリアル化するときに許容される最大の深さを取得または設定します。既定値は 0 で、最大の深さが 64 であることを示します。 | |
PropertyNameCaseInsensitive | 逆シリアル化中に、プロパティの名前で大文字と小文字を区別しない比較が使用されるかどうかを決定する値を取得または設定します。 既定値は false です。 | |
★ | PropertyNamingPolicy | オブジェクトのプロパティの名前を、キャメルケース形式などの別の形式に変換するために使用されるポリシーを指定する値を取得または設定するか、プロパティ名を変更しない場合は null にします。 |
★ | ReadCommentHandling | 逆シリアル化中にコメントを処理する方法を定義する値を取得または設定します。 |
★ | WriteIndented | JSON で整形出力を使用する必要があるかどうかを定義する値を取得または設定します。 既定では、JSON は余分な空白なしでシリアル化されます。 |