もくじ
→https://qiita.com/tera1707/items/4fda73d86eded283ec4f
json関連記事
https://qiita.com/tera1707/items/4fda73d86eded283ec4f#json
やりたいこと
jsonファイルを読み書きするときに、使えるライブラリがいくつかあるようだが、できれば.netで標準で使えるものを使って行いたい。
やり方
DataContractJsonSerializerクラスをつかう。
準備
参照にSystem.Runtime.Serialization
を追加する。
サンプル(.cs)
jsonファイルからデータを読んで、クラスオブジェクトに展開する。(デシリアライズ)
そのあと、クラスオブジェクトの中身をファイルにjson文字列として保存する。(シリアライズ)
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
namespace JsonTest
{
class Program
{
static void Main(string[] args)
{
// デシリアライズ(jsonファイル→クラスオブジェクト)
string jsonFilePath = @"TestData.json";
var data = new List<PointData>();
using (var ms = new FileStream(jsonFilePath, FileMode.Open))
{
var serializer = new DataContractJsonSerializer(typeof(List<PointData>));
data = (List<PointData>)serializer.ReadObject(ms);
}
// シリアライズ(クラスオブジェクト→jsonファイル)
string jsonFilePathOut = @"TestDataOut.json";
using (var stream = new MemoryStream())
using (var fs = new FileStream(jsonFilePathOut, FileMode.Create))
using (var sw = new StreamWriter(fs))
{
var serializer = new DataContractJsonSerializer(typeof(List<PointData>));
serializer.WriteObject(stream, data);
var str2write = Encoding.UTF8.GetString(stream.ToArray());
sw.Write(str2write);
}
// 終わり
Console.WriteLine("json読み書き完了");
Console.ReadLine();
}
}
[DataContract]
public class PointData
{
[DataMember]
public List<double> small { get; set; }
[DataMember]
public List<double> large { get; set; }
}
}
サンプル(.json)
使ったjsonはこちら
[
{
"small": [
123.456,
789.012
],
"large": [
987.654,
654.321
]
},
{
"small": [
111.456,
222.012
],
"large": [
333.654,
444.321
]
}
]
デシリアライズしたときのウォッチ
※サンプルのTestData.jsonをちょっといじって、2つ目のデータの方の「Large」を試しに削ったjsonを呼んだ時のウォッチ
jsonメモ
-
[
と]
でくくったところは配列になる。 - クラスで書くと、
List<〇〇>
になる。 - jsonの先頭が
[
で配列の場合は、new DataContractJsonSerializer(typeof(List<PointData>));
のように、コンストラクタに渡す型がList<〇〇>
になる。 - 先頭以外だと、クラスのプロパティの型が
List<〇〇>
になる。 -
{
と}
でくくったところはオブジェクトになる。 - オブジェクトは、C#ではクラスやプロパティに該当する。
- 今回サンプルにはないが、数値以外にもjsonにはデータを持たせられる様子。(こちらによると、下表のようなものを持たせられる)
データ型 | 備考 |
---|---|
数値 | |
文字列 | ダブルクォーテーションでくくる。 |
真偽値 | true or false。小文字にする。 |
配列 | コンマ区切りの角かっこでくくる。 |
オブジェクト | コンマ区切りの波かっこでくくる。キーと値のペアをコロンで対にする。キーはダブルクォーテーションでくくる。 |
null | デシリアライズ時、C#のクラスにはあるのにjsonにないようなときに、jsonを読むとnullになる |
C#のクラスとjsonの対応付けイメージ
今回のサンプルのC#とjsonの対応付けは下記のようなイメージ。
備考
データを入れるクラスに[DataContract]
、プロパティに[DataMember]
をつけてるが、これらをつけてなくても問題なくシリアライズ/デシリアライズできた。
その辺の、アトリビュートをつけたとき、つけてないときの動作の比較はこちらのサイトが超絶詳しい。そちらを参照。
追記(20/01/06) データ用クラスの簡単な作り方
jsonデータのためのクラスを簡単につくる方法があることが分かった。
下記の記事を参照。
→DataContractJsonSerializerで読み書きするjsonデータのためのクラスを簡単につくる
参考
DataContractJsonSerializerの詳細動作
>本クラスの使い方から、[DataContract]をつけたとき、つけないときの動作の比較など、わかりやすく解説されてる。このページ見れば全部わかる。
http://mokake.hatenablog.com/entry/2017/09/12/195656
DataContractJsonSerializer Class (MS Docs)
https://docs.microsoft.com/ja-jp/dotnet/api/system.runtime.serialization.json.datacontractjsonserializer?view=netframework-4.8
jsonのデータの種類
https://soseiji-memo.hatenablog.com/entry/json