我想对我的Azure DocumentDb进行SQL查询。我现在有一个非常混乱的代码,但它看起来像是
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
上,但说实话,我尝试了很多版本而且没有结果......我在这里错过了什么?
答案 0 :(得分:2)
resourceLink的值取决于您使用的是基于ID的路由还是基于路由的路由。
看起来您正在使用基于ID的路由 所以,对于查询,resourceLink应该是
string.Format("dbs/{0}/colls/{1}/docs", databaseId, collectionId);
和resourceId应该相同,
string.Format("dbs/{0}/colls/{1}", databaseId, collectionId)
POST有点不同,因为它需要设置特定的标头。 使用REST API查询DocumentDB资源的REST文档应记录所需内容 - https://msdn.microsoft.com/en-us/library/azure/dn783363.aspx
有关resourceLink&amp;的更多示例resourceId和一个工作eample看看我们刚刚发布的.NET示例中的REST。 https://github.com/Azure/azure-documentdb-dotnet/blob/d3f8e9c731bc92816d023719e7e780b7a9546ca2/samples/rest-from-.net/Program.cs#L151-L164
答案 1 :(得分:1)
对于POST我使用这样的东西:
var resourceLink = string.Format("dbs/{0}/colls/{1}", DataBaseName, DocumentCollectionName);
using (var client = GetClient(
"POST",
resourceLink,
"docs",
PrimaryKey))
{
try
{
var content =
new StringContent("{\"query\":\"SELECT * FROM root\"}", Encoding.UTF8, "application/query+json");
content.Headers.ContentType.CharSet = "";
var r = client.PostAsync(
new Uri(
new Uri(EndpointUri), resourceLink + "/docs"), content).Result;
}
catch (Exception ex)
{
}
}}
它对我有用