Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Azure cosmosdb 401(未经授权)尝试通过REST API查询DocumentDb时_Azure Cosmosdb - Fatal编程技术网

Azure cosmosdb 401(未经授权)尝试通过REST API查询DocumentDb时

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(

我想对我的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));
}
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以进行实际查询。