C#でJSON形式のデータを出力してみた
思うところ有りまして、C#でJSON形式のデータを出力してみました。自分でJSON形式のテキストデータを作るのではなくて、シリアライザーを使ってインスタンスをJSONに変換してみました。
目次
環境
Visual Studio 2015 Express for Windows Desktop
JSONって?
JavaScript Object Notation (JSON)というのは、JavaScript発祥のデータ形式ですね。詳しくは ウィキペディア で。
実は今回初めて使ってみました。
シリアライザーの準備
シリアル化というのは、アプリ実行時のデータの実体(インスタンス)をJSON形式に変換することです。XMLでも同様にシリアル化(シリアライズ)、逆シリアル化(デシリアライズ)と言いますね。
ググるとJSON用のライブラリがいくつかあるようなのですが、今回はC#のシリアライザーを使います。
JSONシリアライザーを使用するにあたって、参照の追加が必要です。
まず、ソリューションエクスプローラーの「参照」を右クリックし、右クリックメニューの中から「参照の追加」を選択します。
そうするとソリューションマネージャーウィンドウが開くので、「アセンブリ」→「フレームワーク」と選択し、「System.Runtime.Serialization」にチェックを付けて、「OK」ボタンをクリックします。
そうすると、「参照」の子にSystem.Runtime.Serializationが追加されます。
シリアル化の手順
MSDN に記載されている手順そのままです。
元になるデータのインスタンスを作る。
メモリーストリームを作る。
DataContractJsonSerializerクラスのインスタンスを作る。
DataContractJsonSerializer.WriteObject(Stream, Object)メソッドで、データをメモリストリームに書き出す。
メモリーストリームから出力の処理をする。
DataContractJsonSerializerクラス
DataContractJsonSerializerクラス は、JSON形式へのシリアル化と逆シリアル化をするクラスです。
今回使ったコンストラクターは下記です。
DataContractJsonSerializer(Type type)
引数 |
型 |
内容 |
---|---|---|
type |
Type |
シリアル化・逆シリアル化するインスタンスの型。 |
他にもいろいろありますので、 DataContractJsonSerializerクラス を参照してください。
DataContractJsonSerializer.WriteObjectメソッド
DataContractJsonSerializer.WriteObject メソッド はシリアル化(インスタンス→JSON)に使用するメソッドです。
今回使った構文は下記です。
WriteObject(Stream stream, object data)
引数 |
型 |
内容 |
---|---|---|
stream |
Stream |
書き込み先のストリーム。 |
data |
object |
書き込むデータを格納しているインスタンス。 |
試してみた
データを保持するインスタンスを作って、そのインスタンスをシリアル化して、シリアル化したJSONデータをコンソールに出力する、コンソールアプリを作ってみました。インスタンスが入れ子構造を持っているという、ちょっとひねくれた形です。
シリアル化するデータ
下図のように、SubFoldersというプロパティに自分と同じクラスのインスタンスのコレクションを持つインスタンスです。
コード
コードは下記の様にしてみました。
using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Collections.ObjectModel;
namespace json_trial
{
class Program
{
static void Main(string[] args)
{
// JSONに変換するデータを作る。
FolderInformation f = new FolderInformation();
f.Name = "f";
f.Size = 512;
FolderInformation g = new FolderInformation();
g.Name = "g";
g.Size = 1024;
f.SubFolders.Add(g);
FolderInformation h = new FolderInformation();
h.Name = "h";
h.Size = 65536;
f.SubFolders.Add(h);
// データをJSON形式にシリアル化して、メモリーストリームに出力する。
MemoryStream st = new MemoryStream(); // メモリーストリームを作成
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(FolderInformation)); // シリアライザーを作成
serializer.WriteObject(st, f); // シリアライザーで出力
// メモリーストリームの内容をコンソールに出力する。
st.Position = 0;
StreamReader reader = new StreamReader(st);
Console.WriteLine(reader.ReadToEnd());
}
}
/// <summary>
/// データ保持用のクラス
/// </summary>
[DataContract]
public class FolderInformation
{
[DataMember]
public string Name { get; set; }
[DataMember]
public Int64 Size { get; set; }
private Collection<FolderInformation> _subfolders = new Collection<FolderInformation>();
[DataMember]
public Collection<FolderInformation> SubFolders
{
get { return _subfolders; }
}
}
}
説明を書いておこうと思いますが、シリアル化と出力部分はコメントの通りですので省きます。
データ保持用のクラスについてですが、コレクションのプロパティの設定の仕方がちょっと変わっています。上記コードのFolderInformationクラスのSubFolersプロパティのことですが、getterだけを設定してRead Onlyにしています。そして外部から参照されたときは非公開のコレクションのフィールド_subfoldersを返します。
「setterが無かったら、どうやってデータを追加するんだ?」と思ってしまうのですが、Add()メソッドでオブジェクトを追加できます。なぜでしょうか。ドット演算子とかの働きを勉強すれば良いのでしょうが、何をみたら良いかも分らないので、動作から仕組みを想像してみます。
FolderInformation f = new FolderInformation();
FolderInformation g = new FolderInformation();
f.SubFolders.Add(g);
上記のコードが実行されたとき、Add()メソッドさんはインスタンスgを追加する先として、インスタンスfのSubFoldersプロパティを参照して追加先のコレクションの実体がどこにあるのか知るのではないでしょうか。必要なのはコレクションのインスタンスがどこにあるかということなので、setterにデータを入れるのではなくて、getterからコレクションインスタンスを取得すると。
あくまでも想像です。私はこういう風に理解することにしましたということを表明してるだけです。信じないでください。
実行結果
出力結果は下記の様になりました。
{"name":"f","Size":512,"SubFolders":[{"name":"g","Size":1024,"SubFolders":[]},{"name":"h","Size":2048,"SubFolders":[]}]}
入れ子構造で出力されてますね。
公開日
広告
C#でデータ処理カテゴリの投稿
- C#でDataAdapterを使ってAccessのデータベースを読み書きしてみた
- C#でDataAdapterを使ってAccessのデータベースを読み書きしてみた(OleDb編)
- C#でDataGridに表示するデータを操作してみた
- C#でDataTableのカラムのデータ型を読んでみた
- C#でDataTableの自動インクリメントをしてみた
- C#でJSON形式のデータを出力してみた
- C#でLinq to objectの結果をDataTableにしてみた
- C#でSQLite3のデータベースを使ってみる(ADO.NET ファクトリーデザインパターン)
- C#でSQLiteを使ってみる(インストール)
- C#でコレクションの要素の数を調べる
- C#でコレクションを内部結合してみた
- C#でコレクションを左外部結合してみた
- C#でコレクションを昇順または降順に並び替える
- C#で渡された配列を加工して配列で返す関数について注意すること
- C#のキューを試してみた
- C#のスタックを試してみた