C#でzipcloudのAPIを動かしたかったのでJSONをパースしようと思ったのですが、無駄につまづいたのでメモ。
郵便番号から県とか住所を引いてきて自動挿入してくれる感じのやつが作りたかったので試してました。
参考サイト
やったこと
System.Text.Jsonのインストール
VisualStudioのメニューバーから、ツール→NuGetパッケージマネージャー→ソリューションのNuGetパッケージマネージャーの管理を開きます。
参照タブで System.Text.Json を検索してインストールしたら利用できました。
作成者はMicrosoftです。
取得部分のコード
//検索したい郵便番号 string zipcode = "000-0000"; //URL string url = "https://zipcloud.ibsnet.co.jp/api/search?zipcode=" + zipcode; using (var webClient = new System.Net.WebClient()) { // エンコーディングをUTF-8にしておく(取得してからEncoding変えてもパースできなかった) webClient.Encoding = System.Text.Encoding.UTF8; // JSONのテキストを取得 string jsonStr = webClient.DownloadString(url); // JSON文字列をオブジェクトに変換 Rootobject obj = JsonSerializer.Deserialize<Rootobject>(jsonStr); // 正常にデータ取得できたか確認 if (obj.status == 200 && obj.results != null) { // なんらかの処理 } }
JSONパースするためのクラス
パース用のクラス(今回はRootobject)を作成しないといけないので作成します。
上記のページにある、レスポンスサンプルをコピーして、Visual Studioのメニューバーから、編集→型式を選択して貼り付け→JSONをクラスとして貼り付ける。
で貼り付けると下記のようなクラスができるので、今回はそちらを利用しました。
public class Rootobject { public object message { get; set; } public Result[] results { get; set; } public int status { get; set; } } public class Result { public string address1 { get; set; } public string address2 { get; set; } public string address3 { get; set; } public string kana1 { get; set; } public string kana2 { get; set; } public string kana3 { get; set; } public string prefcode { get; set; } public string zipcode { get; set; } }
おまけ:出てきたエラー
webclientでエンコーディングを指定するまでは、下記のようなエラーが出ていました。
一見、改行やタブのような制御文字っぽいものでつまづいているように見えたのでそうかなと思っていました。
System.Text.Json.JsonException: ''0x0A' is invalid within a JSON string. The string should be correctly escaped. Path: $.results[0].address1 | LineNumber: 4 | BytePositionInLine: 32.' System.Text.Json.JsonException: ''0x09' is invalid within a JSON string. The string should be correctly escaped. Path: $.results[0].address1 | LineNumber: 0 | BytePositionInLine: 61.'
その時解消のために書いたコードはこんなかんじ。
URLからとってきたjson文字列をbyteにしてエンコードかけています。見るからにうまくいくか怪しいコードです。
string url = "https://zipcloud.ibsnet.co.jp/api/search?zipcode="+ zipcode; using (var webClient = new System.Net.WebClient()) { string jsonStr = webClient.DownloadString(url); //バイト配列に変換 byte[] bytesUTF8 = System.Text.Encoding.Default.GetBytes(jsonStr); //バイト配列をUTF8の文字コードとしてStringに変換 string stringSJIS = System.Text.Encoding.UTF8.GetString(bytesUTF8); // 改行とタブの置換 stringSJIS = stringSJIS.Replace("\n", "");// 0x0Aの置換 stringSJIS = stringSJIS.Replace("\t", "");// 0x09の置換 Rootobject obj = JsonSerializer.Deserialize(stringSJIS); Console.Write(obj); }
改行やタブを置換したのですが、下記のようなエラー。
System.Text.Json.JsonException: 'The JSON value could not be converted to System.String. Path: $.results[0].address1 | LineNumber: 0 | BytePositionInLine: 55.'
置換後の文字列を見ると中途半端に文字化けしていました。(「埼玉県」が「埼玉省E」みたいな感じに一部だけ文字化けする)
途中までエンコードの方法が悪いのかと思っていたのですが、このあたりでいいかげん「変換前の文字列がまずいんだろうな…」と気づきました。
なので、webclientにエンコーディングをつけたら正常にパースできた次第です。そりゃそうだよね…。UTF-8のデータはもとからUTF-8でよむべきだよね…。ごめんな…。
おわり。