简体   繁体   English

Azure功能-Cosmos DB删除文档问题

[英]Azure Function - Cosmos DB Delete Document Issue

I'm new to Azure and am trying to create a simple CRUD web application with Azure functions and Cosmos DB, using C#. 我是Azure的新手,正在尝试使用C#创建具有Azure函数和Cosmos DB的简单CRUD Web应用程序。 So far, I've successfully implemented two functions, one to write a document to the database and another to read all documents from the database. 到目前为止,我已经成功实现了两个功能,一个功能是将文档写入数据库,另一个功能是从数据库读取所有文档。 I've also implemented a function to delete a document but I cannot get it to work, even when using the Azure portal's function test utility. 我还实现了删除文档的功能,但是即使使用Azure门户的功能测试实用工具,也无法正常工作。 The problem occurs with the call to DeleteDocumentAsync, which causes an exception to be thrown. 调用DeleteDocumentAsync会发生问题,这将引发异常。

The complete run.csx code (simplified by using a hard-coded document SelfLink) is shown below: 完整的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);
    }
}

The function.json file is shown below: 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
}

The exeption's stack trace is shown below. 附件的堆栈跟踪如下所示。 The top of the stack trace refers to 'GenerateKeyAuthorizationSignature'. 堆栈跟踪的顶部引用“ GenerateKeyAuthorizationSignature”。 Is the root cause a permissions issue? 根本原因是权限问题吗? I would appreciate any help in solving this. 对于解决此问题,我将不胜感激。

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 excepti Microsoft.Azure.Documents.Client.GatewayServiceConfigurationReader.d__0.MoveNext()-从堆栈结束跟踪引发异常的先前位置---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在Microsoft.Azure.Documents.Routing.GlobalEndpointManager.d__0。 MoveNext()---从上一个引发异常的位置开始的堆栈结束跟踪--- Microsoft.System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)处System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) .Azure.Documents.Client.GatewayServiceConfigurationReader.d__b.MoveNext()-从上一个位置开始的堆栈结束跟踪 on 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.Compil 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在Microsoft.Azure.Documents.Client.DocumentClient.d__35d.MoveNext() ---从先前引发异常的位置开始的堆栈跟踪---位于Microsoft.Azure的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task任务)处的System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)。 Documents.Client.DocumentClient.d__29.MoveNext()---从上一个引发异常的位置开始的堆栈结束跟踪---在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)在System.Runtime.CompilerServices.TaskAwaiter Microsoft.Azure.Documents.Client.DocumentClient.d__44.MoveNext()上的.HandleNonSuccessAndDebuggerNotification(任务任务)-从上一个引发异常的位置开始的堆栈结束跟踪-在System.Runtime.Compil erServices.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.BackoffRetryUtility 1.<>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.BackoffRetryUtility 1.d__1b.MoveNext()--- End of stack trace from previous location where exception was thrown --- at Microsoft.Azure.Documents. System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的erServices.TaskAwaiter.ThrowForNonSuccess(任务任务),Microsoft.Azure.Documents.Client.DocumentClient.d__cf.MoveNext()的堆栈任务跟踪-从上一位置开始的堆栈结束跟踪在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)的System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)的Microsoft.Azure.Documents.BackoffRetryUtility 1.<>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.BackoffRetryUtility 1.d__1b.MoveNext()--- 1.<>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.BackoffRetryUtility处从引发异常的先前位置开始的堆栈结束跟踪。 BackoffRetryUtility 1.<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.BackoffRetryUtility 1.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 BackoffRetryUtility 1.<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.BackoffRetryUtility 1.d__a.MoveNext()上的1.<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.BackoffRetryUtility -从上一个引发异常的位置开始的堆栈结束跟踪-在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task任务)在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)在Submission#0.d__3.MoveNext()在D:\\ home \\ blah \\ run.csx:line 34

First, when using Azure Functions, keep the DocumentClient static so the instance is shared across executions, this is a performance improvement. 首先,使用Azure Functions时,请将DocumentClient保持静态,以便在执行之间共享实例,这是性能上的改进。

With that in mind, you can create this Function: 考虑到这一点,您可以创建以下功能:

#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 : functions.json

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM