[C#]JSON.Netを使ってWebサービスから取得したJSONを扱うときのメモ。

Webサービスが提供するWebAPIからJSON形式で情報をもらう。
今やWebAPIなどの受け渡しに使うのはJSONが当たり前になっています。
そこで、C#でWebAPIなどからJSON形式の文字列を受信した時の扱いについてメモ。JSONの扱いにはJSON.Netを使用します。
ここでは、JSON.Netを使用してJSON文字列を連想配列により操作する方法とユーザー定義(クラス定義)に置き換える方法を試します。

JSON.Net
http://json.codeplex.com/

実際のWebサービスを使って試す。
HeartRailsExpressのWebAPIを使用して全国の鉄道情報をJSONで受け取り、C#フォームアプリケーションで使用したいと思います。

HeartRailsExpress – API
http://express.heartrails.com/api.html

今回使用するAPIは、
都道府県情報取得 API,路線情報取得 API,駅情報取得 APIの3つです。

やりたいこと。
・全国の路線、駅情報を提供するWebAPIからJSONを取得。
・WebAPIを使用して、都道府県名の列挙。
・WebAPIを使用して、都道府県別の路線情報の列挙。
・WebAPIを使用して、路線情報から駅情報の取得。
・駅情報を利用して地図上に位置を表示する。

実行画面

※このアプリケーションでは取得したJSON文字列とJSON文字列から生成したXML(XDocument)をTextBoxにそれぞれ表示しています。

連想配列によるデータの操作。
JSONの連想配列によるデータの操作はJSON.Netのデシリアライズ関数(JsonConvert.DeserializeObject関数)にNewtonsoft.Json.Linq.JContainer型を返すように指定します。

◇都道府県名の列挙。路線情報の列挙。
都道府県情報APIは次のJSONを返します。

{
    "response" : {
        "prefecture" : ["北海道","青森県",・・・,"沖縄県"]
    }
}       

JSON.Netを使ってNewtonsoft.Json.Linq.JContainer型に変換しリストボックスに表示します。
※argにはWebAPIから取得したJSON文字列が入っています。

                    var jobj = JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JContainer>(arg);
                    listBoxKen.Items.AddRange(jobj["response"]["prefecture"].ToArray());

路線情報は都道府県名の列挙を行うやりかたと同じです。

                    var jobj = JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JContainer>(arg);
                    listBoxRosen.Items.AddRange(jobj["response"]["line"].ToArray());

◇駅情報の列挙。
駅情報には緯度経度、前の駅名、次の駅名など様々な情報が含まれます。

{
    "response" : {
        "station" : [
             {"x":139.738535,"next":"大崎","prev":"田町","y":35.628135,"line":"JR山手線","postal":"1080075","name":"品川","prefecture":"東京都"},
             {"x":139.728246,"next":"五反田","prev":"品川","y":35.61994,"line":"JR山手線","postal":"1410032","name":"大崎","prefecture":"東京都"}
        ]
    }
}       

駅情報の中から駅名(name)だけを列挙し、リストボックスに表示します。

                    var jobj = JsonConvert.DeserializeObject<Newtonsoft.Json.Linq.JContainer>(arg);
                    listBoxEki.Items.AddRange(jobj["response"]["station"].Select(p=>p["name"]).ToArray());

ユーザー定義(クラス定義)によるデータの操作。
JSON文字列をユーザー定義型に変換するにはクラス定義が必要になります。クラスを定義する際の注意すべきことはJSONのキーとクラスのプロパティ名が完全一致、JSONの値とクラスの型が変換可能である、ということが重要です。

◇クラス定義

    class MyJsonFormat
    {
        /// <summary>
        /// 都道府県情報
        /// </summary>
        public class PrefectureResponse
        {
            public class Prefecture
            {
                public string[] prefecture { get; set; }
                public Prefecture()
                {
                    prefecture = new string[] { };
                }
            }
            public Prefecture response { get; set; }

            public PrefectureResponse()
            {
                response = new Prefecture();
            }
        }

        /// <summary>
        /// 路線情報
        /// </summary>
        public class LineResponse
        {
            public class Line
            {
                public string[] line { get; set; }
                public Line()
                {
                    line = new string[] { };
                }
            }

            public Line response { get; set; }
            public LineResponse()
            {
                response = new Line();
            }
        }

        /// <summary>
        /// 駅情報
        /// </summary>
        public class StationResponse
        {
            public class Station
            {
                public double x{get;set;}
                public string next{get;set;}
                public string prev{get;set;}
                public double y { get; set; }
                public string line { get; set; }
                public string postal { get; set; }
                public string name { get; set; }
                public string prefecture { get; set; }

                public Station()
                {
                    x = y = 0;
                    next = prev = line = postal = name = prefecture = "";
                }
            }

            public class Stations
            {
                public Station[] station { get; set; }

                public Stations()
                {
                    station = new Station[] { };
                }
            }

            public Stations response { get; set; }

            public StationResponse()
            {
                response = new Stations();
            }
        }
    }

◇都道府県名の列挙。路線情報の列挙。
JSON.Netのデシリアライズ関数に定義したPrefectureResponseクラスを指定します。PrefectureResponseクラスのインスタンスから都道府県名(prefecture)を取り出し、リストボックスに表示します。

                    var jobj = JsonConvert.DeserializeObject<MyJsonFormat.PrefectureResponse>(arg);
                    listBoxKen.Items.AddRange(jobj.response.prefecture);

路線情報の列挙もJSONをLineResponseクラスへと変換し、路線名をリストボックスに表示します。

                    var jobj = JsonConvert.DeserializeObject<MyJsonFormat.LineResponse>(arg);
                    listBoxRosen.Items.AddRange(jobj.response.line);

◇駅情報の列挙。
駅情報の列挙もJSONをStationResponseクラスへと変換し、駅名(name)を取り出してリストボックスに表示します。

                    var jobj = JsonConvert.DeserializeObject<MyJsonFormat.StationResponse>(arg);
                    listBoxEki.Items.AddRange(jobj.response.station.Select(p => p.name).ToArray());

後のことを考えるなら、クラス定義を使用したほうがよい。
その場限りのコードであればわざわざクラス定義を書く必要性が無いかもしれませんが、ユーザー定義型に変換してしまったほうがデータの扱いが後々楽になります。

今回作成したソースはこちら

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


This blog is kept spam free by WP-SpamFree.