4

API トークンを取得するために http ポスト リクエストを作成しようとしています。成功すると、アクセス トークン、トークン タイプ (ベアラー)、および expires_in の文字列値が返されるはずです。

私が持っているコードは、私が期待していた一般的なものです。しかし、何らかの理由で、400「リモート サーバーがエラーを返しました。不正な要求」という例外がスローされます。私はこれを修正するためにあらゆることを試みてきましたが、結果は変わりません。

コードをデバッグして出力ウィンドウに結果を表示すると、「このストリームはシーク操作をサポートしていません」というデータ ストリームに関する例外があります。

Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();

私の疑いは、それがエンコードされている方法であるpostDataが原因で発生することです。私のクライアントシークレットは次のようなものです:

g/gOvqf5R+FTZZXbwsCbp0WsQjF9B0bl87IBQ8VAJ2Q=

シークレット自体の文字をエンコードして、不正なリクエストを作成しますか?

私もこれを POSTMAN で試してみましたが、結果が得られたので、API には何もありません。依頼内容に戻ります。コンソールアプリです。以下にコードを貼り付けます。事前にご協力いただきありがとうございます。

public static APIModel GenerateApiKey()
    {
        var appSettings = ConfigurationManager.AppSettings;

        try
        {
            var urlToCall = string.Format("https://app.example.com/token");
            var uri = new Uri(urlToCall);

            var request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = "POST";

            string postData = "grant_type=client_credentials&client_id=" + appSettings["my_client_id"] + "&client_secret=" + appSettings["my_client_secret"];
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = byteArray.Length;


            Stream dataStream = request.GetRequestStream();
            dataStream.Write(byteArray, 0, byteArray.Length);
            dataStream.Close();

            var response = (HttpWebResponse)request.GetResponse();

            APIModel bearerToken;

            using (StreamReader sr = new StreamReader(response.GetResponseStream()))
            {
                string jsonFromServer = sr.ReadToEnd();
                bearerToken = JsonConvert.DeserializeObject<APIModel>(jsonFromServer); 
            }

            response.Close();

            return bearerToken;

        }
        catch (Exception e)
        {
            throw new Exception("Error getting a response from API  " + e.Message);
        }

    }
4

2 に答える 2

2

リモート サーバーは、何らかの不正なデータを送信したために 400 エラーを返しています。応答を取得して、正確なエラーを把握できる場合があります。リモート サーバーからさらに多くの情報が得られる可能性があります。ただし、投稿データに問題が 1 つあります。クライアント シークレットは URL エンコードする必要があります。その内容を見ると、=記号で終わっていることがわかります。特殊文字として解釈されます。また、文字列の作成についてもう少し明確にしたいので、これはうまくいくでしょう:

var postItems = new List<KeyValuePair<string, string>>
{
    new KeyValuePair<string, string>("grant_type", "client_credentials"),
    new KeyValuePair<string, string>("client_id", "client_credentials"),
    new KeyValuePair<string, string>("client_secret", "client_credentials"),
};

string postData = string.Join("&", 
    postItems.Select (kvp => 
        string.Format("{0}={1}", kvp.Key, HttpUtility.UrlEncode(kvp.Value))));
于 2015-07-09T13:47:34.067 に答える
0

クライアント ID とシークレットは、フォーム データを形成する際に個別に URL エンコードする必要がありました。更新された postData:

string postData = "grant_type=client_credentials&client_id=" + HttpUtility.UrlEncode(appSettings["my_client_id"]) + "&client_secret=" + HttpUtility.UrlEncode(appSettings["my_client_secret"]);
于 2015-07-09T13:46:20.273 に答える