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 を使用していない場合、その他の例はクールです。