我想對Azure DocumentDb進行SQL查詢。我有一個相當混亂的代碼,但現在這是它的外觀嘗試通過REST API查詢DocumentDb時發生401(未授權)
public string GetResources(string collection) {
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Add("x-ms-date", utc_date);
client.DefaultRequestHeaders.Add("x-ms-version", "2015-08-06");
client.DefaultRequestHeaders.Add("x-ms-documentdb-isquery", "True");
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/query+json"));
//GET a document
var verb = "POST";
var resourceType = "docs";
var resourceLink = string.Format("dbs/{0}/colls/{1}/docs", databaseId, collection);
var resourceId = (idBased) ? resourceLink : "";
var authHeader = GenerateAuthToken(verb, resourceId, resourceType, masterKey, "master", "1.0");
Console.WriteLine(authHeader);
client.DefaultRequestHeaders.Remove("authorization");
client.DefaultRequestHeaders.Add("authorization", authHeader);
var q = new DbQuery {
Query = "SELECT * FROM root"
};
var postData = new List<KeyValuePair<string, string>>();
postData.Add(new KeyValuePair<string, string>("query", q.Query));
return PostAsync(resourceLink, postData, client).Result;
}
public async Task<string> PostAsync(string uri, List<KeyValuePair<string, string>> data, HttpClient httpClient)
{
var content = new FormUrlEncodedContent(data);
Console.WriteLine(httpClient.DefaultRequestHeaders.Authorization);
var response = await httpClient.PostAsync(new Uri(baseUri, uri), content);
response.EnsureSuccessStatusCode();
string postContent = await response.Content.ReadAsStringAsync();
return await Task.Run(() => postContent);
}
string GenerateAuthToken(string verb, string resourceId, string resourceType, string key, string keyType, string tokenVersion)
{
var hmacSha256 = new System.Security.Cryptography.HMACSHA256 { Key = Convert.FromBase64String(key) };
string verbInput = verb ?? "";
string resourceIdInput = resourceId ?? "";
string resourceTypeInput = resourceType ?? "";
string payLoad = string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}\n{1}\n{2}\n{3}\n{4}\n",
verb.ToLowerInvariant(),
resourceType.ToLowerInvariant(),
resourceId,
utc_date.ToLowerInvariant(),
""
);
byte[] hashPayLoad = hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
string signature = Convert.ToBase64String(hashPayLoad);
return System.Net.WebUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture, "type={0}&ver={1}&sig={2}",
keyType,
tokenVersion,
signature));
}
我有一個請求由它的ID來獲得文件和我使用同樣的方法。它工作正常。我相信這個問題可能與我resourceLink
,但老實說,我嘗試了很多版本,都沒有結果..我在這裏錯過了什麼?
您是否嘗試過格式化後的內容作爲JSON,而不是URL編碼?這將解釋爲什麼你的GET基於一個ID的作品,但這個POST不。另一方面,你得到401的事實表明內容不是問題,但auth頭是。另外,如果我建議使用REST API,你願意接受另一個問題的答案嗎? –
謝謝@LarryMaccherone!但我是否正確,至少,「dbs/{0}/colls/{1}/docs」是查詢獲取文檔列表的正確途徑? – alexxjk
我看到你已經使用了我們的REST文檔中的示例代碼。也許看看https://gist.github.com/ryancrawcour/cc5d898b924ebc9635d1,它將向您展示如何在各種資源上進行各種GET操作。你從根目錄中選擇*,就像我在做一個集合中所有文檔的GET一樣。如果你喜歡,我可以擴展這個例子並添加POST來做實際的查詢。 –