c# - Azure Function - Cosmos DB 删除文档问题

标签 c# azure azure-cosmosdb

我是 Azure 新手,正在尝试使用 C# 使用 Azure 函数和 Cosmos DB 创建一个简单的 CRUD Web 应用程序。到目前为止,我已经成功实现了两个功能,一个将文档写入数据库,另一个从数据库读取所有文档。我还实现了删除文档的功能,但即使使用 Azure 门户的功能测试实用程序,也无法使其工作。调用 DeleteDocumentAsync 时会出现问题,这会导致引发异常。

完整的 run.csx 代码(通过使用硬编码文档 SelfLink 进行简化)如下所示:

#r "Microsoft.Azure.Documents.Client"
using System.Net;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;

private static bool success;

public static HttpResponseMessage Run(HttpRequestMessage req, out object deletionDocument, TraceWriter log)
{
    string endpointUrl = "https://blahblah.documents.azure.com:443/"; // ** Copied from 'URI' in Read-Write Keys screen.
    string authorizationKey = "blahblahblah"; // ** Copied from 'PRIMARY KEY' in Read-Write Keys screen.
    ConnectionPolicy connectionPolicy = new ConnectionPolicy();
    connectionPolicy.RetryOptions.MaxRetryAttemptsOnThrottledRequests = 3;
    connectionPolicy.RetryOptions.MaxRetryWaitTimeInSeconds = 60;
    connectionPolicy.RequestTimeout = new TimeSpan(0, 0, 30);
    deletionDocument = null;

    using (DocumentClient client = new DocumentClient(new Uri(endpointUrl), authorizationKey, connectionPolicy))
    {
        success = true;
        Task t = DeleteDocument(client, log);
    }

    return success
        ? req.CreateResponse(HttpStatusCode.OK, "Deletion succeeded")
        : req.CreateResponse(HttpStatusCode.BadRequest, "Deletion failed");
}

private static async Task DeleteDocument(DocumentClient client, TraceWriter log)
{
    try
    {
        await client.DeleteDocumentAsync("dbs/p3wOAA==/colls/p3wOAPsBIwA=/docs/p3wOAPsBIwAEAAAAAAAAAA==/");
    }
    catch (Exception ex)
    {
        success = false;
        log.Info("ex: " + ex.StackTrace);
    }
}

function.json 文件如下所示:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "delete"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "documentDB",
      "name": "deletionDocument",
      "databaseName": "taskDatabase",
      "collectionName": "MsgCollection",
      "createIfNotExists": false,
      "connection": "apw-messages-id_DOCUMENTDB",
      "direction": "out"
    }
  ],
  "disabled": false
}

该异常的堆栈跟踪如下所示。堆栈跟踪的顶部引用“GenerateKeyAuthorizationSignature”。根本原因是权限问题吗?如果您能帮助解决此问题,我将不胜感激。

at Microsoft.Azure.Documents.AuthorizationHelper.GenerateKeyAuthorizationSignature(String verb, Uri uri, NameValueCollection headers, IComputeHash stringHMACSHA256Helper, String clientVersion) at Microsoft.Azure.Documents.Client.GatewayServiceConfigurationReader.d__0.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.Routing.GlobalEndpointManager.d__0.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.Client.GatewayServiceConfigurationReader.d__b.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.Client.DocumentClient.d__35d.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.Client.DocumentClient.d__29.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.Client.DocumentClient.d__44.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.Client.DocumentClient.d__cf.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.BackoffRetryUtility1.<>c__DisplayClass2.<<ExecuteAsync>b__0>d__4.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.BackoffRetryUtility1.d__1b.MoveNext()--- End of stack trace from previous location where exception was thrown --- at Microsoft.Azure.Documents.BackoffRetryUtility1.<ExecuteRetry>d__1b.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.Azure.Documents.BackoffRetryUtility1.d__a.MoveNext()--- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Submission#0.d__3.MoveNext() in D:\home\blah\run.csx:line 34

最佳答案

首先,使用 Azure Functions 时,保持 DocumentClient 静态,以便在执行之间共享实例,这是性能改进。

考虑到这一点,您可以创建此函数:

#r "Microsoft.Azure.Documents.Client"
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using System.Net;

private static string endpointUrl = "https://blahblah.documents.azure.com:443/"; // ** Copied from 'URI' in Read-Write Keys screen.
private static string authorizationKey = "blahblahblah"; // ** Copied from 'PRIMARY KEY' in Read-Write Keys screen.
private static DocumentClient client = new DocumentClient(new Uri(endpointUrl), authorizationKey, new ConnectionPolicy() {
    RequestTimeout = new TimeSpan(0, 0, 30),
    RetryOptions = new RetryOptions() {
        MaxRetryAttemptsOnThrottledRequests = 3,
        MaxRetryWaitTimeInSeconds = 60
    }
});

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    bool success = true;

    try {
        await client.DeleteDocumentAsync("dbs/p3wOAA==/colls/p3wOAPsBIwA=/docs/p3wOAPsBIwAEAAAAAAAAAA==/");
        // or you could use the UriFactory if you have the document id
        //Uri documentUri = UriFactory.CreateDocumentUri("name of database","name of collection","document id");
        //await client.DeleteDocumentAsync(documentUri);
    }
    catch(Exception ex){
        success = false;
        log.Info("ex: " + ex.StackTrace);
    }

    return success
        ? req.CreateResponse(HttpStatusCode.OK, "Deletion succeeded")
        : req.CreateResponse(HttpStatusCode.BadRequest, "Deletion failed");
}

functions.json:

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": [
        "delete"
      ]
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    }
  ],
  "disabled": false
}

关于c# - Azure Function - Cosmos DB 删除文档问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48206150/

相关文章:

c# - 安装时如何指定sql server的连接字符串

c# - 我如何在 c# 中使用 Microsoft.Office.Interop.Excel.Application 写入 excel

c# - XAML 中的对象初始值设定项

azure - 如何从Azure Key Vault读取和更新Azure Logic App的parameters.json文件中的 secret 信息

azure - Cosmos 中的热分区会增加 RU 消耗吗?

C# 应用程序 - 如何在 xaml 表单中显示网站?

c# - 使用 ServiceConfiguration (Azure) 中的连接字符串自定义 DbContext

c# - 无法将 CloudTask 添加到 Azure Batch

python - 如何使用 python SDK 过滤 Azure 表中的特定行

azure-cosmosdb - 对于大量记录,我能否获取 Cosmos DB 表中所有记录的计数?