続・REST Webサービスの作成が僕には難しすぎたので、誰にでも分かるよう手順を残す。（クライアント編）

#はじめに
前回の記事の続きです。

[REST Webサービスの作成が僕には難しすぎたので、誰にでも分かるよう手順を残す。](http://qiita.com/yz2cm/items/8e7790026b7697843219)

前回はサービス側プログラムの作成と動作確認まで行いましたが、今回はサービス側にリクエストを投げるクライアント側のコマンドプログラムを作ってみたいと思います。

#前提

本記事で作成したプログラムの実行は、前回作成したサービスプログラム「ProductsApp」が起動していることを前提としています。「ProductsApp」の作成や起動の方法については、[前回の記事](http://qiita.com/yz2cm/items/8e7790026b7697843219)を参照下さい。

#本記事で作成するプログラムのI/F仕様

引数に指定したURLでサービス側にリクエストを投げ、サービス側からレスポンスされたデータを標準出力します。

```bat:プログラムの実行例（コマンドプロンプト）
>RestClient.exe http://localhost:51585/api/products/1
id: 1 name: Tomato Soup category: Groceries price: 1.0
```

#１．プロジェクトの作成

今回はコマンドとして作成するため**「コンソールアプリ(.NET Framework)」**を選択します。名前は**「RestClient」**としておきます。

![new_project.png](https://qiita-image-store.s3.amazonaws.com/0/51871/525c7b8e-4810-24bd-dba3-909fded49b80.png)

#２．JSONシリアライザパッケージのインストール

「NuGet パッケージの管理」から、`System.Runtime.Serialization.Json`をインストールします。

![system_runtime_serialization_json_1.png](https://qiita-image-store.s3.amazonaws.com/0/51871/b785416f-0833-27e7-a1f0-e79b2ca07760.png)

![system_runtime_serialization_json_2.png](https://qiita-image-store.s3.amazonaws.com/0/51871/c8c380e5-332f-b87c-5e4b-5c60f23fce3a.png)

#３．プログラムの実装（C#）

以下にソースコードをベタ張りしておきます。HTTPリクエスト、レスポンスのところはメソッド名を見れば、何やってるかはなんとなく分かると思います。

```csharp:Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

namespace RestClient
{
    class Program
    {
        static void Main(string[] args)
        {
            var httpRequest = WebRequest.Create(args[0]);
            httpRequest.ContentType = "application/json";
            httpRequest.Method = "GET";

            var httpResponse = httpRequest.GetResponse();
            using (httpResponse)
            {
                using (var resStream = httpResponse.GetResponseStream())
                {
                    var serializer = new DataContractJsonSerializer(typeof(Product));
                    var info = (Product)serializer.ReadObject(resStream);
                    Console.WriteLine("id: {0} name: {1} category: {2} price: {3}",
                        info.Id, info.Name, info.Category, info.Price);
                }
            }
        }
    }

    [DataContract]
    internal class Product
    {
        [DataMember]
        public int Id { get; set; }
        [DataMember]
        public string Name { get; set; }
        [DataMember]
        public string Category { get; set; }
        [DataMember]
        public decimal Price { get; set; }
    }
}
```

注意点としては、サービス側とのインタフェースとなるクラス（`Product`）やそのプロパティの名前（`Id`,`Name`,`Category`,`Price`）は、サービス側で定義した名前に合わせる必要があるということです。**大文字／小文字の違いもNGです**。

ソースコードを書いたら、ビルドします。

#４．動作確認

```bat:実行結果
>RestClient.exe http://localhost:51585/api/products/1
id: 1 name: Tomato Soup category: Groceries price: 1.0
```

おめでとうございます。

#５．配列が返された場合

ところで配列が返ってきた場合、どうするかって？
コード中の`Product`を`Product[]`に修正するだけでOKです。

```csharp:Program.cs
using (var resStream = httpResponse.GetResponseStream())
{
    //var serializer = new DataContractJsonSerializer(typeof(Product));
    //var info = (Product)serializer.ReadObject(resStream);
    //Console.WriteLine("id: {0} name: {1} category: {2} price: {3}", info.Id, info.Name, info.Category, info.Price);
    var serializer = new DataContractJsonSerializer(typeof(Product[]));
    var info = (Product[])serializer.ReadObject(resStream);
    info.ToList().ForEach( x => Console.WriteLine("id: {0} name: {1} category: {2} price: {3}",
        x.Id, x.Name, x.Category, x.Price));
}
```

ということで、できました。

```bat:実行結果
>RestClient.exe http://localhost:51585/api/products
id: 1 name: Tomato Soup category: Groceries price: 1.0
id: 2 name: Yo-yo category: Toys price: 3.75
id: 3 name: Hammer category: Hardware price: 16.99
```

#６．プロキシサーバーの資格情報を設定する

リクエストを投げる前に、以下の一文を加えます。

```csharp:Program.cs
WebRequest.DefaultWebProxy.Credentials = new NetworkCredential("UserName", "Password");
```

#謝辞
HTTPアクセスやJSON解析の方法については、こちらの記事を参考にさせていただきました。

* [argius note / C#でHTTP経由でJSONを取得して値を取り出す](http://argius.hatenablog.jp/entry/20131113/1384352397)

「６．プロキシサーバーの資格情報を設定する」は、こちらの記事を参考にさせていただきました。

* [プロキシ環境下で Web API を呼び出す](http://gooner.hateblo.jp/entry/2016/02/22/062314)