Эмулятор хранилища Azure: значение одного из заголовков HTTP имеет неверный формат

Я пишу/отлаживаю функцию Azure с помощью эмулятора хранилища Azure на своем локальном компьютере. К сожалению, я не совсем уверен, какие API мне следует использовать, или правильные URL-адреса для хранилища. Мой код выглядит так:

CosmosClient client = new CosmosClient(storageURL, authKeyString);
Database db = client.GetDatabase("devstoreaccount1");
container = db.GetContainer("leaderboard");
ItemResponse<StoredScore> resp = await container.CreateItemAsync<StoredScore>(newScore);

Входными данными для функции являются:

storageURL = "http://127.0.0.1:10002"
authKeyString = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=="

В последней строке кода выше я получаю исключение:

DocDBTrace Warning: 0 : initializeTask failed Microsoft.Azure.Documents.DocumentClientException: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>InvalidHeaderValue</code>
  <message xml:lang="en-US">The value for one of the HTTP headers is not in the correct format.
RequestId:ed82efd8-6cb8-4a2e-a793-16a38b3c8f2a
Time:2019-12-20T20:07:19.9539313Z</message>
</error>
RequestUri: http://127.0.0.1:10002/;
RequestMethod: GET;
Header: x-ms-version Length: 10;
Header: User-Agent Length: 98;
Header: x-ms-date Length: 29;
Header: Authorization Length: 84;
, Request URI: /, RequestStats: , SDK: Windows/10.0.16299 cosmos-netstandard-sdk/3.4.2
   at Microsoft.Azure.Cosmos.GatewayStoreClient.ParseResponseAsync(HttpResponseMessage responseMessage, JsonSerializerSettings serializerSettings, DocumentServiceRequest request)
   at Microsoft.Azure.Cosmos.GatewayAccountReader.GetDatabaseAccountAsync(Uri serviceEndpoint)
   at Microsoft.Azure.Cosmos.Routing.GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(Uri defaultEndpoint, IList`1 locations, Func`2 getDatabaseAccountFn)
   at Microsoft.Azure.Cosmos.GatewayAccountReader.InitializeReaderAsync()
   at Microsoft.Azure.Cosmos.CosmosAccountServiceConfiguration.InitializeAsync()
   at Microsoft.Azure.Cosmos.DocumentClient.InitializeGatewayConfigurationReaderAsync()
   at Microsoft.Azure.Cosmos.DocumentClient.GetInitializationTaskAsync(IStoreClientFactory storeClientFactory)
   at Microsoft.Azure.Cosmos.DocumentClient.EnsureValidClientAsync()
DocDBTrace Error: 0 : DocumentClientException with status code BadRequest, message: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>InvalidHeaderValue</code>
  <message xml:lang="en-US">The value for one of the HTTP headers is not in the correct format.
RequestId:67e1f70a-c9c8-4aed-892c-964e8ff0f0e1
Time:2019-12-20T20:11:28.0006476Z</message>
</error>
RequestUri: http://127.0.0.1:10002/;
RequestMethod: GET;
Header: x-ms-version Length: 10;
Header: User-Agent Length: 98;
Header: x-ms-date Length: 29;
Header: Authorization Length: 82;
, inner exception: null, and response headers: {
"Server": "Microsoft-HTTPAPI/2.0",
"x-ms-request-id": "67e1f70a-c9c8-4aed-892c-964e8ff0f0e1",
"Date": "Fri, 20 Dec 2019 20:11:27 GMT",
}
DocDBTrace Information: 0 : Fail to reach global gateway http://127.0.0.1:10002/, Microsoft.Azure.Documents.DocumentClientException: <?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>InvalidHeaderValue</code>
  <message xml:lang="en-US">The value for one of the HTTP headers is not in the correct format.
RequestId:67e1f70a-c9c8-4aed-892c-964e8ff0f0e1
Time:2019-12-20T20:11:28.0006476Z</message>
</error>
RequestUri: http://127.0.0.1:10002/;
RequestMethod: GET;
Header: x-ms-version Length: 10;
Header: User-Agent Length: 98;
Header: x-ms-date Length: 29;
Header: Authorization Length: 82;
, Request URI: /, RequestStats: , SDK: Windows/10.0.16299 cosmos-netstandard-sdk/3.4.2
   at Microsoft.Azure.Cosmos.GatewayStoreClient.ParseResponseAsync(HttpResponseMessage responseMessage, JsonSerializerSettings serializerSettings, DocumentServiceRequest request)
   at Microsoft.Azure.Cosmos.GatewayAccountReader.GetDatabaseAccountAsync(Uri serviceEndpoint)
   at Microsoft.Azure.Cosmos.Routing.GlobalEndpointManager.GetDatabaseAccountFromAnyLocationsAsync(Uri defaultEndpoint, IList`1 locations, Func`2 getDatabaseAccountFn)
Exception thrown: 'Microsoft.Azure.Documents.DocumentClientException' in System.Private.CoreLib.dll

Эмулятор хранилища Azure запущен, и я могу управлять им в обозревателе хранилища.

Может ли кто-нибудь помочь мне понять, что я сделал неправильно? Использую ли я для этого «лучший» API?


person Nevo    schedule 20.12.2019    source источник
comment
Вы на 100% уверены, что эмулятор работает по адресу 127.0.0.1:10002? Этот вопрос и ответы на него также могут помочь.   -  person Ian Kemp    schedule 21.12.2019
comment
Это может быть глупый вопрос, но почему вы вызываете Storage с классами Cosmos DB?   -  person juunas    schedule 21.12.2019
comment
Ян, если бы эмулятор не был по этому URL, я бы не получил ответа.   -  person Nevo    schedule 21.12.2019


Ответы (1)


Основываясь на вашем коде, вы хотите использовать CosmosDB для хранения ваших StoredScore данных. Если это так, вам следует использовать эмулятор CosmosDB вместо эмулятора хранилища.

Пожалуйста, выполните следующие шаги, чтобы ваш код работал:

  1. Установите и запустите эмулятор CosmosDB

  2. Создайте базу данных Cosmos с коллекцией на вашем локальном компьютере:

введите здесь описание изображения

В этом случае имя моей базы данных Cosmos — localdb, а имя моего контейнера — localcontainer.

Вы можете найти свой хост и ключ CosmosDB здесь: введите здесь описание изображения

3. Создайте функцию Azure, активируемую http, в VS локально, это мой код ниже:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.Cosmos;

namespace cosmostest
{
    public static class Function1
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            CosmosClient client = new CosmosClient("https://localhost:8081/", "<your key here>");
            Database db = client.GetDatabase("<your local db name>");
            Container container = db.GetContainer("<your local container name>");
            var newScore = new StoredScore() { id ="1", name ="stan", score =100 };
            ItemResponse<StoredScore> resp = await container.CreateItemAsync<StoredScore>(newScore);
            return new OkObjectResult(resp.StatusCode);
        }
    }

    public class StoredScore
    {

        public string id { get; set; }
        public string name { get; set; }
        public int score { get; set; }
    }

}

Запустите функцию и активируйте ее, если вы получите «201» в качестве ответа, ваши данные были успешно сохранены в вашей локальной космической БД: введите здесь описание изображения

Данные в БД местного космоса: введите здесь описание изображения

Надеюсь, поможет.

person Stanley Gong    schedule 23.12.2019
comment
Ага. Я перепутал эмулятор хранилища и эмулятор Cosmos DB. Спасибо. - person Nevo; 26.12.2019