C# exercises (d) REST & JSON

Visual Studio community 2015 アカウントについて (学内専用)

  1. WebBrowser (基本)
  2. Form(自動操作)
  3. HttpClient
  4. REST & JSON ←今週

RESTとは

RESTとは、RESTはREpresentational State Transferの略。2000年にRoy Fielding氏が提唱した、分散システムにおいて複数のソフトウェアを連携させるのに適した設計原則の集合。また、狭義には、それをWebに適用したソフトウェアの設計様式のこと。一般には後者の意味で用いられることがほとんどである。RESTの世界では、ネットワーク上のコンテンツ(リソース)を一意なURLで表すのが基本。各リソース(URL)に対してGET,POST,PUT,DELETEでリクエストを送信しレスポンスをXMLやjsonなどで受け取る形式(レスポンスのフォーマット形式は指定されていない)。

REST APIをを作る前に先人はどのような設計をしていたのかを見てみましょう。今ではTwitterやfacebook,Github、Amazonなど大きいところではだいたいAPIを提供しているので、お手本は山ほどあります。URL設計やリクエスト・レスポンス、HTTPヘッダなどに着目して見比べてみましょう。

Twitter REST API
レスポンスの情報量が多いので、どういった情報を返すべきか参考になります。
Github API
一番綺麗にまとまっているAPIだと思います。リクエスト・レスポンスがRESTらしく、とても綺麗。

JSONとは

JSONとは、JavaScriptにおけるオブジェクトの表記法を応用したデータ形式。 JSONで表記されたデータは、JavaScript上ではコードとして実行するだけで読み込みが完了する。JSONでは、データ全体を配列またはJavaScriptにおけるオブジェクト(キーと値のペアを列挙した構造体)として記述する。

JSONというのは「データを表現するための記法(≒文法)」です。シンプルなデータであれば、文法など気にせずにただ書けば問題ありません。少々複雑でも、我々は「表」という記法をしっているため、ある程度の複雑さには対応できます。しかし、表で表すのが困難な程度の複雑な構造を持つデータを表現しなければならないことは多々あります。このように、表形式では表現が困難な構造のデータを、人間に対するある程度の可読性を残しつつ、コンピュータに対しても伝達できるような記法、その1つがJSONです。そしてJSON形式で記述したデータのことを、JSON-textといいます。

chenlabのメンバーをJSON-textで表現

{
“name”   : “chenlab”,
“member3” : [ “14TE485”, “14TE406”, “14TE410”, “14TE449” , “14TE461″”, “14TE465″”, “14TE470”],
“member4” : [ “13TE466”, “13TE477”, “13TE486”, “13TE520” , “12TE412″”, “13TE457″”, “13TE405”],
“count”  : 4
}

 

C#でJSON

Newtonsoft.Jsonのインストール

C#でJSON扱うときは、いくつ方法があり、ここはNewtonsoft.Jsonののライブラリを使う。

NuGetパッケージ管理を開く

nuget

Newtonsoft.Jsonを選択して、インストールしてください。

2016-07-14

 

JSONデータサンプル

http://wp-api.xyz/wp-json/posts

先週のプログラムでサンプルデータを取得するように変更してください。

ダウンロード:web_get2 (2)

JSONをクラスとして貼り付け

JSONのデータ構造をC#のクラス定義に変換する。

取得したサンプルデータをコピーして、メニューの「JSONをクラスとして貼り付け」で、プログラムのnamespaceの最後部に貼り付けください。

jsonpaste

JSONプログラミング

16 行に下記の分を入れえてください

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Linq;

デザイン画面に、「button1」ボタンと、「listBox1」リストボックスを追加してください。

デザインのbutton1をダブルクリックし、DeserializeObject処理を入れてください。

private void button1_Click(object sender, EventArgs e)
{
    var json = HTTP_Results.Text;
    var posts = JsonConvert.DeserializeObject<Class1[]>(json);
    foreach(Class1 post in posts)
    {
        listBox1.Items.Add(post.ID);
    }
    // string saveJson = JsonConvert.SerializeObject(posts, Formatting.Indented);

}

実行画面

これて、Jsonデータ(ブログの投稿)の取得、Deserialize、そして(ブログID)表示ができた。

スクリーンショット 2016-07-15 11.35.51

最終プログラム構造

  • Namespace web_get2
    • Class Form1 : Form
      • Form1
      • Quit_Click
      • Request_Click
      • button1_Click
    • Class Rootobject (JSON データ構造)
    • Class Meta (JSON データ構造)
    • Class Links (JSON データ構造)
    • Class Terms (JSON データ構造)
    • 。。。

最終プログラム

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// for httpclient
using System.Net.Http;
using System.Net;
using System.IO;
using System.Runtime.Serialization;
// using System.Runtime.Serialization.Json;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Linq;

namespace web_get2
{


    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Quit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private async void Request_Click(object sender, EventArgs e)
        {
            if (ProxyOn.Checked)
            {
                // デフォルト プロキシ情報を取得して、資格情報を設定する 
                var proxy = WebRequest.DefaultWebProxy;
                proxy.Credentials = new NetworkCredential(ProxyID.Text, ProxyPW.Text);
            }
            var client = new HttpClient();
            string response = await client.GetStringAsync(URL.Text);
            HTTP_Results.Text = response;

        }

        private void button1_Click(object sender, EventArgs e)
        {
            var json = HTTP_Results.Text;
            var posts = JsonConvert.DeserializeObject<Class1[]>(json);
            foreach (Class1 post in posts)
            {
                listBox1.Items.Add(post.ID);
            }
            // string saveJson = JsonConvert.SerializeObject(posts, Formatting.Indented);
        }
    }


    public class Rootobject
    {
        public Class1[] Property1 { get; set; }
    }

    public class Class1
    {
        public int ID { get; set; }
        public string title { get; set; }
        public string status { get; set; }
        public string type { get; set; }
        public object author { get; set; }
        public string content { get; set; }
        public object parent { get; set; }
        public string link { get; set; }
        public DateTime date { get; set; }
        public DateTime modified { get; set; }
        public string format { get; set; }
        public string slug { get; set; }
        public string guid { get; set; }
        public string excerpt { get; set; }
        public int menu_order { get; set; }
        public string comment_status { get; set; }
        public string ping_status { get; set; }
        public bool sticky { get; set; }
        public string date_tz { get; set; }
        public DateTime date_gmt { get; set; }
        public string modified_tz { get; set; }
        public DateTime modified_gmt { get; set; }
        public Meta meta { get; set; }
        public object featured_image { get; set; }
        public Terms terms { get; set; }
    }

    public class Meta
    {
        public Links links { get; set; }
    }

    public class Links
    {
        public string self { get; set; }
        public string author { get; set; }
        public string collection { get; set; }
        public string replies { get; set; }
        public string versionhistory { get; set; }
    }

    public class Terms
    {
        public Category[] category { get; set; }
    }

    public class Category
    {
        public int ID { get; set; }
        public string name { get; set; }
        public string slug { get; set; }
        public string description { get; set; }
        public string taxonomy { get; set; }
        public object parent { get; set; }
        public int count { get; set; }
        public string link { get; set; }
        public Meta1 meta { get; set; }
    }

    public class Meta1
    {
        public Links1 links { get; set; }
    }

    public class Links1
    {
        public string collection { get; set; }
        public string self { get; set; }
    }
}

 

C# exercises (c) Web3 HttpClient

Visual Studio community 2015 アカウントについて (学内専用)

  1. WebBrowser (基本)
  2. Form(自動操作)
  3. HttpClient ←今週
  4. REST & JSON

いままで、WebBrowser コントロールを利用して、 Webサイトを表示と操作プログラムを作りました。

今回は直接 http 通信に HttpClient クラスを使用 するプログラムを作ります。

HTTPとは

httpとは、代表的な通信プロトコルの一つで、インターネット上でWebサーバー(サイトの公開側)と、クライアント(ブラウザ:サイトを閲覧する側)が、相互に通信するために使用される仕組みです。

もっと言うと、Webサーバーとクライアント間で、HTML(Webページを作成するための言語)で記載された情報をやりとりするための仕組みです。

この「http」がないと、インターネット上のサイトを見ることができなくなるので、今や無くてはならない仕組みとなります。

r10zu01-2

HTTPコマンド

主なHTTPコマンドには次のようなものがあります。

GET 指定したページの取得を要求します。
HEAD メッセージヘッダを要求します。
POST フォームに入力したデータを送る
PUT サーバーへデータをアップロードする
DELETE サーバー上のデータを削除する

 

HTTPコマンド応答メッセージ

主な応答メッセージには、次のようなものがあります。

200 OK 正常に取得できた
301 恒久的に移転した
302 一時的に移転した
403 Forbidden アクセス拒否
404 Not Found ファイルが見つからない

 

HttpClient 通信プログラム

デザイン

web_get

 

  • Form
    • Form1
  • TextBox
    • textBox1  —
      • Name : URL
      • Text : http://wp-api.xyz
    • textBox2  —
      • Name :  ProxyID
      • Text : (your_proxy_id)
    • textBox3  —
      • Name :  ProxyPW
      • PasswordChar : *
      • Text : (your_proxy_password)
    • textBox4  —
      • Name : HTTP_Results
      • Multiline : True
  • Button
    • button1 —
      • Name : Quit
    • button2 —
      • Name : Request
  • CheckBox
    • checkBox1 —
      • Name : ProxyOn

 

プログラム

HttpClient クラス

// for httpclient
using System.Net.Http;
using System.Net;
using System.IO;
using System.Runtime.Serialization;
// using System.Runtime.Serialization.Json;

Quit ボタン

        private void Quit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

Requestボタン

private async void Request_Click(object sender, EventArgs e)
{
    if (ProxyOn.Checked)
    {
        // デフォルト プロキシ情報を取得して、資格情報を設定する 
        var proxy = WebRequest.DefaultWebProxy;
        proxy.Credentials = new NetworkCredential(ProxyID.Text, ProxyPW.Text);
    }
    var client = new HttpClient();
    string response = await client.GetStringAsync(URL.Text);
    HTTP_Results.Text = response;

}

最終プログラム:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
// for httpclient
using System.Net.Http;
using System.Net;
using System.IO;
using System.Runtime.Serialization;
// using System.Runtime.Serialization.Json;


namespace web_get2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Quit_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        private async void Request_Click(object sender, EventArgs e)
        {
            if (ProxyOn.Checked)
            {
                // デフォルト プロキシ情報を取得して、資格情報を設定する 
                var proxy = WebRequest.DefaultWebProxy;
                proxy.Credentials = new NetworkCredential(ProxyID.Text, ProxyPW.Text);
            }
            var client = new HttpClient();
            string response = await client.GetStringAsync(URL.Text);
            HTTP_Results.Text = response;

        }
    }
}

実行結果

web_get2