【问题标题】:Azure Function with CosmosDb Binding Proper Local Setup具有 CosmosDb 绑定的 Azure 函数正确的本地设置
【发布时间】:2019-05-17 15:19:06
【问题描述】:

我确定我在这里遗漏了一些简单的东西,但我无法让它工作。我已经在本地安装了 Azure Storage Simulator,并通过 Visual Studio 2019 创建了 Azure Function 2.0。

我可以在没有 CosmosDb 绑定的情况下运行该函数,如下所示:

local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "EndpointUri": "https://localhost:8081",
    "PrimaryKey": "<KEY_HERE>"
  }
}

Function.cs

public static class Function
{
    [FunctionName("func")]
    public static async Task Run(
        [TimerTrigger("0 * * * * *")] TimerInfo myTimer,
        ILogger log
    )
    {
        log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");

        var endpointUri = new Uri(Environment.GetEnvironmentVariable("EndpointUri", EnvironmentVariableTarget.Process));
        var primaryKey = Environment.GetEnvironmentVariable("PrimaryKey");

        using (var client = new DocumentClient(endpointUri, primaryKey))
        {
            var queryOptions = new FeedOptions { MaxItemCount = -1 };
            var documents = client.CreateDocumentQuery<Doc>(UriFactory.CreateDocumentCollectionUri("db_id", "col_id"), queryOptions);

            foreach (var document in documents)
            {
              ...
            }
        }
    }
}

代码按预期运行并获取我在本地存储模拟器中的文档。

不过,我想将其切换为使用 CosmosDb 绑定,但似乎找不到让它工作所需的魔法咒语。

我将Function.cs 上的方法签名更新为:

public static async Task Run(
            [TimerTrigger("0 * * * * *")] TimerInfo myTimer,
            ILogger log,
            [CosmosDB(
                databaseName: "db_id",
                collectionName: "col_id",
                ConnectionStringSetting = "AzureWebJobsStorage",
                SqlQuery = "SELECT * FROM col_id")
            ] IEnumerable<Doc> documents
        )

当我运行它时,我收到以下错误:

[2019 年 5 月 17 日下午 3:09:29] 执行“func”(失败, Id=8326b1c4-3dd5-461d-b8de-d777c5b925d8) [2019 年 5 月 17 日下午 3:09:29] System.Private.CoreLib:执行函数时出现异常:func。 Microsoft.Azure.WebJobs.Host:异常绑定参数“文档”。 Microsoft.Azure.DocumentDB.Core:值不能为空。 [2019 年 5 月 17 日 3:09:29 PM] 参数名称:authKeyOrResourceToken。

我尝试了许多其他的修补方法,但都没有成功。

第一个是使用默认的完整显式连接字符串: 在Azure docs 中找到"AzureWebJobsStorage": "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;TableEndpoint=http://127.0.0.1:10002/devstoreaccount1;QueueEndpoint=http://127.0.0.1:10001/devstoreaccount1;",

知道如何更改上述内容以在本地对我的 Azure 存储模拟器成功执行吗?

【问题讨论】:

    标签: c# azure azure-functions azure-cosmosdb


    【解决方案1】:

    CosmosDB 绑定中的 ConnectionStringSetting 是 Cosmos DB 帐户的连接字符串设置,而不是 Azure 存储。查看每个属性的official docs

    第 1 步:使用有效的 Cosmos DB 连接字符串(可能是模拟器)向 local.settings.json 添加新设置。

    {
      "IsEncrypted": false,
      "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet",
        "EndpointUri": "https://localhost:8081",
        "PrimaryKey": "<KEY_HERE>",
        "CosmosDBConnectionString": "AccountEndpoint=https://localhost:8081;AccountKey=<KEY_HERE>;",
      }
    }
    

    第 2 步:修改您的 Function.cs 以使用新设置:

    public static async Task Run(
        [TimerTrigger("0 * * * * *")] TimerInfo myTimer,
        ILogger log,
        [CosmosDB(
            databaseName: "db_id",
            collectionName: "col_id",
            ConnectionStringSetting = "CosmosDBConnectionString",
            SqlQuery = "SELECT * FROM col_id")
        ] IEnumerable<Doc> documents
    )
    

    如果您想手动运行查询或执行其他操作,您可以随时从绑定中拉入DocumentClient 实例:

    public static async Task Run(
        [TimerTrigger("0 * * * * *")] TimerInfo myTimer,
        ILogger log,
        [CosmosDB(
            databaseName: "db_id",
            collectionName: "col_id",
            ConnectionStringSetting = "CosmosDBConnectionString")
        ] DocumentClient documentClient
    )
    

    附带说明,每当您手动创建DocumentClient 时,请遵循these guidelines,切勿在每次执行时在using 语句中创建DocumentClient 实例。

    【讨论】:

    • 感谢您提供的非常有帮助的答案。回复:using,文档告诉您不要将HttpClient 放入使用中。 DocumentClient 只是一个包装器,这就是为什么你不应该使用 using 语句的原因吗?
    • 该文档有一个针对 DocumentClient 的特定部分,因为 Cosmos DB 的 performance guidelines 讲述了使用单例模式。部分原因是客户端在内部使用HttpClient。这一切都归结为aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多