7

TL;DR -- 認証ヘッダーを使用して JSON 文字列を REST ホストに送信するにはどうすればよいですか? 私は 3 つの異なるアプローチを試しましたが、匿名型で機能するアプローチが見つかりました。匿名型を使用できないのはなぜですか? "Group-Name" という変数を設定する必要がありますが、ハイフンは有効な C# 識別子ではありません。

バックグラウンド

JSON を POST する必要がありますが、本文とコンテンツ タイプを正しく取得できません

機能 #1 - 匿名型で動作します

コンテンツ タイプとデータは正しいですが、匿名タイプは使用したくありません。文字列を使いたい

  static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody)
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri(restURLBase);
        client.DefaultRequestHeaders.Add("Auth-Token", AuthToken);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        // StringContent content = new StringContent(postBody);

        var test1 = "data1";
        var test2 = "data2";
        var test3 = "data3";

        var response = client.PostAsJsonAsync(RESTUrl, new { test1, test2, test3}).Result;  // Blocking call!
        if (!response.IsSuccessStatusCode)
        {
            Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            return;
        } 
    }

出力 #1

AnonymousTypes + PostAsJsonAsync を使用すると、コンテンツ タイプとデータは正しくなりますが、匿名タイプは使用したくありません。

POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1
Auth-Token: --- REDACTED -----
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: api.dynect.net
Content-Length: 49
Expect: 100-continue

{"test1":"data1","test2":"data2","test3":"data3"}

機能 2 - 期待どおりに動作しない

文字列を取り、それを StringContent オブジェクトに入れます。これには、コンテンツ タイプの変更という副作用があります。

  static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody)
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri(restURLBase);
        client.DefaultRequestHeaders.Add("Auth-Token", AuthToken);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        StringContent content = new StringContent(postBody);

        var response = client.PostAsync(RESTUrl, content).Result;  // Blocking call!
        if (!response.IsSuccessStatusCode)
        {
            Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            return;
        } 
    }

出力 #2

StringContent + PostAsync を使用するとコンテンツ タイプが間違っている

POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1
Auth-Token: ---- REDACTED -------
Accept: application/json                      // CORRECT
Content-Type: text/plain; charset=utf-8       // WRONG!!!
Host: api.dynect.net
Content-Length: 100
Expect: 100-continue

{"rdata" : ["rname" : "dynect.nfp.com", "zone" : "ABCqqqqqqqqqqqqYYYYYtes3ss.com"], "ttl" : "43200"}
        // ^^ THIS IS CORRECT

機能 #3 - 期待どおりに動作しない

contentType が正しく設定されていることがわかっているのでPostAsJsonAsync、そのメソッドを使用してみましょう。(動作しません)

    static void PostData(string restURLBase, string RESTUrl, string AuthToken, string postBody)
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri(restURLBase);
        client.DefaultRequestHeaders.Add("Auth-Token", AuthToken);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        StringContent content = new StringContent(postBody);

        var response = client.PostAsJsonAsync(RESTUrl, content).Result;  // Blocking call!
        if (!response.IsSuccessStatusCode)
        {
            Console.WriteLine("{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
            return;
        } 
    }

出力 #3

StringContent + PostAsJsonAsync を使用すると、コンテンツ タイプは正しく、POST 本文は正しくありません

POST https://api.dynect.net/REST/Zone/ABCqqqqqqqqqqqqYYYYYtes3ss.com HTTP/1.1
Auth-Token: -- REDACTED ---
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: api.dynect.net
Content-Length: 74
Expect: 100-continue

{"Headers":[{"Key":"Content-Type","Value":["text/plain; charset=utf-8"]}]}

質問

私がやりたいことは、JSON を文字列として、または実行時に定義された動的オブジェクトとして、正しい HTTP コンテンツ タイプと特別な「Auth-Token」ヘッダーを付けてサーバーに送信することだけです。

servicestack などの WebAPI を使用していない場合、その他の例はクールです。

4

2 に答える 2

2

HttpContent は抽象クラスであるため、インスタンスを直接セットアップすることはできません。必要に応じて、サブクラスのいずれかを使用する必要があります。ほとんどの場合、コンストラクターで応答の文字列値、エンコーディング、およびメディアの種類を設定できる StringContent: http://msdn.microsoft.com/en-us/library/system.net.http.stringcontent。 aspx

からの回答HttpClient PostAsync 2 番目のパラメーターの HttpContent を設定するにはどうすればよいですか?

于 2014-01-11T18:22:50.687 に答える