Azure cosmosdb 401(未经授权)尝试通过REST API查询DocumentDb时
我想对我的Azure DocumentDb进行SQL查询。我现在有一个相当混乱的代码,但它看起来就是这样Azure cosmosdb 401(未经授权)尝试通过REST API查询DocumentDb时,azure-cosmosdb,Azure Cosmosdb,我想对我的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(
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));
}
publicstringgetresources(字符串集合){
var client=new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Add(“x-ms-date”,utc\U日期);
client.DefaultRequestHeaders.Add(“x-ms-version”、“2015-08-06”);
client.DefaultRequestHeaders.Add(“x-ms-documentdb-isquery”,“True”);
client.DefaultRequestHeaders.Accept.Add(新的System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(“应用程序/查询+json”);
//拿到文件
动词var=“POST”;
var resourceType=“docs”;
var resourceLink=string.Format(“dbs/{0}/colls/{1}/docs”,databaseId,collection);
变量resourceId=(idBased)?resourceLink:;
var authHeader=GenerateAuthToken(动词,resourceId,resourceType,masterKey,“master”,“1.0”);
Console.WriteLine(authHeader);
client.DefaultRequestHeaders.Remove(“授权”);
client.DefaultRequestHeaders.Add(“authorization”,authHeader);
var q=newdbquery{
Query=“从根目录中选择*
};
var postData=新列表();
添加(新的KeyValuePair(“query”,q.query));
返回PostAsync(resourceLink、postData、client);
}
公共异步任务PostAsync(字符串uri、列表数据、HttpClient HttpClient)
{
var内容=新的FormUrlEncodedContent(数据);
WriteLine(httpClient.DefaultRequestHeaders.Authorization);
var response=wait-httpClient.PostAsync(新Uri(baseUri,Uri),content);
response.EnsureSuccessStatusCode();
字符串postContent=wait response.Content.ReadAsStringAsync();
返回等待任务。运行(()=>postContent);
}
string GenerateAuthToken(字符串动词、字符串资源ID、字符串资源类型、字符串键、字符串键类型、字符串令牌版本)
{
var hmacSha256=new System.Security.Cryptography.hmacSha256{Key=Convert.FromBase64String(Key)};
字符串verbInput=动词??”;
字符串resourceIdInput=resourceId??“”;
字符串resourceTypeInput=resourceType??“”;
字符串负载=string.Format(System.Globalization.CultureInfo.InvariantCulture,“{0}\n{1}\n{2}\n{3}\n{4}\n”,
动词.ToLowerInvariant(),
resourceType.ToLowerInvariant(),
智囊团,
utc_date.ToLowerInvariant(),
""
);
byte[]hashPayLoad=hmacSha256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(payLoad));
字符串签名=Convert.ToBase64String(hashPayLoad);
返回System.Net.WebUtility.UrlEncode(String.Format(System.Globalization.CultureInfo.InvariantCulture),“type={0}&ver={1}&sig={2}”,
键类型,
令牌版本,
签署);;
}
我有一个通过Id获取文档的请求,我使用相同的方法。它很好用。我相信问题可能出在我的
resourceLink
上,但老实说,我尝试了很多版本,但都没有结果。。我错过了什么 resourceLink的值将取决于您使用的是基于id的路由还是基于rid的路由
看起来您正在使用基于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文档应记录所需内容-
关于resourceLink&resourceId和一个正在工作的eample的更多示例,请查看我们刚刚发布的.NET示例的其余部分。
对于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)
{
}
}}
这对我很有用你有没有尝试过将帖子内容格式化为JSON而不是URL编码?这就解释了为什么基于id的GET可以工作,但这篇文章却不能。另一方面,您得到401的事实表明内容不是问题所在,但auth头是问题所在。另外,您是否愿意接受我建议使用RESTAPI的另一个问题的答案?谢谢@LarryMaccherone!但是,至少“dbs/{0}/colls/{1}/docs”是进行查询以获取文档列表的正确路径,这一点我是对的吗?我看到您使用了REST文档中的示例代码。也许看一看,它将向您展示在各种资源上执行各种GET操作的示例。您的select*from root与我对集合中的所有文档执行GET的操作相同。如果您愿意,我可以扩展此示例并向其添加POST以进行实际查询。