質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.01%

C# CoincheckのAPIを実行したい。

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 2,826

AMK

score 214

お世話になります。
C#の勉強をしたいと思い
下記のサイトより
https://kokenji.net/coincheck-api/
コードを拝借してAPIを実行してみましたが

どうしてもinternal async Task<string>の Sendの部分で
CS0116のエラーが回避出来ず先輩方のお力をお借りしようと思い書き込みをさせていただきました。

丸投げするのも自分のためにならないので
このサイトを見たら解決できるやヒントなどを頂けると助かります。

お忙しいところ大変恐縮ですがよろしくお願いします
コードは下記のとおりです。

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Crypto_Currency
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private async void button1_ClickAsync(object sender, EventArgs e)
        {
            //coincheck取引所にアクセスする HttpClient
            HttpClient http = new HttpClient();
            http.BaseAddress = new Uri("https://coincheck.com");

            //板情報を取得
            Uri path = new Uri("/api/order_books", UriKind.Relative);//APIの通信URL
            string apiKey = "XXXXX";//APIキー        
            string secret = "XXXXX";//秘密キー
            string method = "GET";//APIメソッド
            string json = await Send(http, path, apiKey, secret, method);


        }
    }

/// <summary>coincheck取引所のAPIを実行します。
/// </summary>
/// <param name="http">取引所と通信する HttpClient。</param>
/// <param name="path">APIの通信URL(取引所サイトからの相対)。</param>
/// <param name="apiKey">APIキー。</param>
/// <param name="secret">秘密キー。</param>
/// <param name="method">APIのメソッド名。</param>
/// <param name="parameters">APIのパラメータのリスト(Key:パラメータ名, Value:パラメータの値)。</param>
/// <returns>レスポンスとして返されるJSON形式の文字列。</returns>
internal async Task<string> Send(HttpClient http, Uri path, string apiKey, string secret, string method, Dictionary<string, string> parameters = null)
{
    if (parameters == null)
        parameters = new Dictionary<string, string>();

    // パラメータ文字列を作成
    var content = new FormUrlEncodedContent(parameters);
    string param = await content.ReadAsStringAsync();

    // nonceにunixtimeを用いる
    string nonce = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();

    // POSTするメッセージを作成
    var uri = new Uri(http.BaseAddress, path);
    string message = nonce + uri.ToString() + param;

    // メッセージをHMACSHA256で署名
    byte[] hash = new HMACSHA256(Encoding.UTF8.GetBytes(secret)).ComputeHash(Encoding.UTF8.GetBytes(message));
    string sign = BitConverter.ToString(hash).ToLower().Replace("-", "");//バイト配列をを16進文字列へ

    // HTTPヘッダをセット
    http.DefaultRequestHeaders.Clear();
    http.DefaultRequestHeaders.Add("ACCESS-KEY", apiKey);
    http.DefaultRequestHeaders.Add("ACCESS-NONCE", nonce);
    http.DefaultRequestHeaders.Add("ACCESS-SIGNATURE", sign);

    // 送信
    HttpResponseMessage res;
    if (method == "POST")
    {
        res = await http.PostAsync(path, content);
    }
    else if (method == "GET")
    {
        res = await http.GetAsync(path);
    }
    else
    {
        throw new ArgumentException("method は POST か GET を指定してください。", method);
    }

    //返答内容を取得
    string text = await res.Content.ReadAsStringAsync();

    //通信上の失敗
    if (!res.IsSuccessStatusCode)
        return "";

    return text;
}
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

こんにちは。

コメントを見て少し気になったので回答してみます。

Classで囲ったアプローチは間違っていないのか?

class Programでメソッドを囲むことでエラーが出なくなることを発見したのは素晴らしいことです。しかし、「なぜclassで囲むことでエラーが出なくなったのか?」を考えるところまで至っていないのが非常にもったいなく感じます。
真面目に解決を目指すなら、「質問のコードを動作させること」より「構文を覚え、その意味を理解すること」を優先するほうが、遠回りですが確実です。

まずは、以下のサイトで「基礎」より下を一通り読んでみることをオススメします。
C# によるプログラミング入門 | ++C++; // 未確認飛行 C

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/01 14:04

    ありがとうございます。

    お陰様で解決できました!!
    まだ理解はできていませんが・・・・w

    ネームスペースから場所を指定しなければダメだったのが原因ですね。

    string json = await Send(http, path, apiKey, secret, method);

    string json = await Program.Send(http, path, apiKey, secret, method);


    internal async Task<string> Send

    internal static async Task<string> Send
    にしてstaticを追加したら動きました!!

    キャンセル

+1

答えではなくヒントということなので。

Compiler Error CS0116

名前空間にフィールドやメソッドのようなメンバーを直接含めることはできません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/30 03:17

    ヒントありがとうございます。

    internal async Taskの部分をClass Programで囲ったらエラーはCS0116エラーは発生しなくなりました!!
    ありがとうございます。

    次に string json = await Send(http, path, apiKey, secret, method);の部分でSendと言う名前は存在しません。CS0103のエラーが出てしまいました。

    Classで囲ったアプローチは間違っていないのか?
    ヒント又は参考URLなど教えて頂くと助かります。

    キャンセル

0

完成系のコード

VS2017で作成
.net 4.6以上を指定する事!
Windowsフォーム アプリケーションで作成

//Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Crypto_Currency
{

   public class Program
    {
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

        /// <summary>coincheck取引所のAPIを実行します。
        /// </summary>
        /// <param name="http">取引所と通信する HttpClient。</param>
        /// <param name="path">APIの通信URL(取引所サイトからの相対)。</param>
        /// <param name="apiKey">APIキー。</param>
        /// <param name="secret">秘密キー。</param>
        /// <param name="method">APIのメソッド名。</param>
        /// <param name="parameters">APIのパラメータのリスト(Key:パラメータ名, Value:パラメータの値)。</param>
        /// <returns>レスポンスとして返されるJSON形式の文字列。</returns>
        internal static async Task<string> Send(HttpClient http, Uri path, string apiKey, string secret, string method, Dictionary<string, string> parameters = null)
        //internal async Task<string> Send(HttpClient http, Uri path, string apiKey, string secret, string method, Dictionary<string, string> parameters = null)
        {
            if (parameters == null)
                parameters = new Dictionary<string, string>();

            // パラメータ文字列を作成
            var content = new FormUrlEncodedContent(parameters);
            string param = await content.ReadAsStringAsync();

            // nonceにunixtimeを用いる
            string nonce = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();

            // POSTするメッセージを作成
            var uri = new Uri(http.BaseAddress, path);
            string message = nonce + uri.ToString() + param;

            // メッセージをHMACSHA256で署名
            byte[] hash = new HMACSHA256(Encoding.UTF8.GetBytes(secret)).ComputeHash(Encoding.UTF8.GetBytes(message));
            string sign = BitConverter.ToString(hash).ToLower().Replace("-", "");//バイト配列をを16進文字列へ

            // HTTPヘッダをセット
            http.DefaultRequestHeaders.Clear();
            http.DefaultRequestHeaders.Add("ACCESS-KEY", apiKey);
            http.DefaultRequestHeaders.Add("ACCESS-NONCE", nonce);
            http.DefaultRequestHeaders.Add("ACCESS-SIGNATURE", sign);

            // 送信
            HttpResponseMessage res;
            if (method == "POST")
            {
                res = await http.PostAsync(path, content);
            }
            else if (method == "GET")
            {
                res = await http.GetAsync(path);
            }
            else
            {
                throw new ArgumentException("method は POST か GET を指定してください。", method);
            }

            //返答内容を取得
            string text = await res.Content.ReadAsStringAsync();

            //通信上の失敗
            if (!res.IsSuccessStatusCode)
                return "";

            return text;
        }
}
}


//From1.cs
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

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

        private async void button1_ClickAsync(object sender, EventArgs e)
        {
            //coincheck取引所にアクセスする HttpClient
            HttpClient http = new HttpClient();
            http.BaseAddress = new Uri("https://coincheck.com");

            //板情報を取得
            Uri path = new Uri("/api/order_books", UriKind.Relative);//APIの通信URL
            string apiKey = "APIキー";//APIキー        
            string secret = "秘密キー";//秘密キー
            string method = "GET";//APIメソッド
            string json = await Program.Send(http, path, apiKey, secret, method);

            textBox1.Text = json;
        }
    }
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.01%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる