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

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

ただいまの
回答率

90.49%

  • C#

    7390questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • API

    1554questions

    APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

c#でzaifのapiで認証が行えない

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,855

hemuhemu779

score 1

前提・実現したいこと

c#でzaifのapiで認証し「get_info」を実行したい。(詳細は以下参照)
ネット上にはC#のサンプルが無くて苦しんでます。
https://corp.zaif.jp/api-docs/trade-api/#method_get_info

発生している問題・エラーメッセージ

httpのリクエストの応答値が以下のようになってしまいます。
response = "{\"success\": 0, \"error\": \"invalid nonce parameter\"}"

該当のソースコード

   class API_ZAIF_get_info
    {
        static readonly Uri endpointUri = new Uri("https://api.zaif.jp");
        static readonly string apiKey = "APIキー";
        static readonly string apiSecret = "APIシークレットキー";

        public async Task<string> TaskStart()
        {
            var method = "POST";
            var path = "/tapi";
            var query = "";
            var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
            var body = @"{
                    ""nonce"": """ + timestamp + @""",
                    ""method"": ""get_info""
                }";
            var data="";
            data = HttpUtility.UrlEncode(body);
            var hash = HASH.SignWithHMACSHA512(data, apiSecret);

            using (var client = new HttpClient())
            using (var request = new HttpRequestMessage(new HttpMethod(method), path + query))
            using (var content = new StringContent(body))
            {
                client.BaseAddress = endpointUri;
                content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                request.Content = content;

                request.Headers.Add("Key", apiKey);
                request.Headers.Add("Sign", hash);

                HttpResponseMessage message = await client.SendAsync(request);
                if (message.IsSuccessStatusCode)
                {
                    var response = await message.Content.ReadAsStringAsync();
                    WriteTextFile_ErrorInfo.write(request.ToString());
                    WriteTextFile_ErrorInfo.write(message.ToString());
                    return response;
                }
                else
                {
                    WriteTextFile_ErrorInfo.write(DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") + "API_ZAIF_get_info");
                    WriteTextFile_ErrorInfo.write(request.ToString());
                    WriteTextFile_ErrorInfo.write(message.ToString());
                    return "false";
                }
            }
      }
}

C#に詳しい方がいたら、何処が悪いか教えて頂きたいです。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

WebClientを使った方法

// 参照に以下の2つを追加する。
// System.Security
// System.Web
//
// NuGetから以下1つのパッケージをインストールする。
// Newtonsoft.Json
using Newtonsoft.Json;
using System;
using System.Net;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace zaif_test
{
    class Program
    {
        static readonly string API_TRADE_ENDPOINT = "https://api.zaif.jp/tapi";
        static readonly string API_KEY = "***";
        static readonly string API_SECRET = "***";

        static void Main()
        {
            var wc = new WebClient();

            // nonce用にunixtimeを用いる
            var unixtime = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

            // POSTするデータ
            var data = HttpUtility.ParseQueryString(string.Empty);
            data.Add("nonce", unixtime.ToString());
            data.Add("method", "get_info");

            // Sign を計算する
            var hash = new HMACSHA512(new UTF8Encoding().GetBytes(API_SECRET)).ComputeHash(new UTF8Encoding().GetBytes(data.ToString()));
            var sign = BitConverter.ToString(hash).ToLower().Replace("-", "");

            // WebClientのヘッダにセットする
            wc.Headers.Set("Key", API_KEY);
            wc.Headers.Set("Sign", sign);

            // POST実行
            var res = wc.UploadValues(API_TRADE_ENDPOINT, data);

            // 結果JSONのデシリアライズ
            var json = JsonConvert.DeserializeObject(new UTF8Encoding().GetString(res));

            // 結果を表示
            Console.WriteLine(json);
        }
    }
}

HttpClientを使った方法

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace zaif_test_httpclient
{
    class Program
    {
        static readonly string API_TRADE_ENDPOINT = "https://api.zaif.jp/tapi";
        static readonly string API_KEY = "***";
        static readonly string API_SECRET = "***";

        static async Task<object> MyTask()
        {
            var httpClient = new HttpClient();

            // nonce用にunixtimeを用いる
            var unixtime = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;

            // POSTするデータ
            var content = new FormUrlEncodedContent(new Dictionary<string, string>
            {
                { "nonce", unixtime.ToString() },
                { "method", "get_info" }
            });

            // Sign を計算する
            var hash = new HMACSHA512(new UTF8Encoding().GetBytes(API_SECRET)).ComputeHash(new UTF8Encoding().GetBytes(await content.ReadAsStringAsync()));
            var sign = BitConverter.ToString(hash).ToLower().Replace("-", "");

            // HttpClientのヘッダにセットする
            httpClient.DefaultRequestHeaders.Add("key", API_KEY);
            httpClient.DefaultRequestHeaders.Add("Sign", sign);

            // POST実行
            var res = await httpClient.PostAsync(API_TRADE_ENDPOINT, content);

            // 結果JSONのデシリアライズ
            var json = JsonConvert.DeserializeObject(await res.Content.ReadAsStringAsync());

            // 結果を返す
            return json;
        }

        static void Main()
        {
            Task.Run(async () =>
            {
                var obj = await MyTask();
                Console.WriteLine(obj);
            }).Wait();

        }
    }
}
{
  "success": 1,
  "return": {
    "funds": {
      "jpy": 0.0,
      "btc": 0.0,
      "mona": 0.0
    },
    "deposit": {
      "jpy": 0.0,
      "btc": 0.0,
      "mona": 0.0
    },
    "rights": {
      "info": 1,
      "trade": 1,
      "withdraw": 1
    },
    "trade_count": 0,
    "open_orders": 0,
    "server_time": 1463503760
  }
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/05/19 09:51

    ご回答ありがとうございます。
    指定された方法で正しい応答を得ることはできました。
    けれども「HttpRequestMessage」を用いた方法をご教授頂けないでしょうか。

    キャンセル

  • 2016/05/19 19:26

    ありがとうございます!

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る

  • C#

    7390questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • API

    1554questions

    APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。