I have a stored procedure in Azure Cosmos DB that will delete record from my Cosmos DB. I tried to call that stored procedure from my Azure function, but I am getting an error related to json parsing when executing the stored procedure (client.ExecuteStoredProcedureAsync
). I already tried changing the partition key to "id" but I still get the same error.
Here is the error message that I got:
"Failed to deserialize stored procedure response or convert it to type 'System.String': Unexpected character encountered while parsing value: {. Path '', line 1, position 1."
Stack trace
at Microsoft.Azure.Documents.Client.StoredProcedureResponse
1..ctor(DocumentServiceResponse response, JsonSerializerSettings serializerSettings)\r\n at Microsoft.Azure.Documents.Client.DocumentClient.ExecuteStoredProcedurePrivateAsync[TValue](String storedProcedureLink, RequestOptions options, IDocumentClientRetryPolicy retryPolicyInstance, CancellationToken cancellationToken, Object[] procedureParams)\r\n at Microsoft.Azure.Documents.BackoffRetryUtility
1.ExecuteRetryAsync(Func1 callbackMethod, Func
3 callShouldRetry, Func1 inBackoffAlternateCallbackMethod, TimeSpan minBackoffForInBackoffCallback, CancellationToken cancellationToken, Action
1 preRetryCallback)\r\n at Microsoft.Azure.Documents.ShouldRetryResult.ThrowIfDoneTrying(ExceptionDispatchInfo capturedException)\r\n at Microsoft.Azure.Documents.BackoffRetryUtility1.ExecuteRetryAsync(Func
1 callbackMethod, Func3 callShouldRetry, Func
1 inBackoffAlternateCallbackMethod, TimeSpan minBackoffForInBackoffCallback, CancellationToken cancellatio nToken, Action1 preRetryCallback)\r\n at FunctionApp2.Function1.Run(HttpRequest req, IAsyncCollector
1 documentsOut, ILogger log) in C:\Users\source\repos\FunctionApp2\FunctionApp2\Function1.cs:line 36"
Stored procedure deleteStoreSample
:
function bulkDeleteProcedure() {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
var response = getContext().getResponse();
var responseBody = {
deleted: 0,
continuation: true
};
query = 'SELECT * FROM c WHERE c.submittedDate > "2002-08-31"';
// Validate input.
if (!query)
throw new Error("The query is undefined or null.");
tryQueryAndDelete();
// Recursively runs the query w/ support for continuation tokens.
// Calls tryDelete(documents) as soon as the query returns documents.
function tryQueryAndDelete(continuation) {
var requestOptions = {continuation: continuation};
var isAccepted = collection.queryDocuments(collectionLink, query, requestOptions, function (err, retrievedDocs, responseOptions) {
if (err)
throw err;
if (retrievedDocs.length > 0) {
// Begin deleting documents as soon as documents are returned form the query results.
// tryDelete() resumes querying after deleting; no need to page through continuation tokens.
// - this is to prioritize writes over reads given timeout constraints.
tryDelete(retrievedDocs);
} else if (responseOptions.continuation) {
// Else if the query came back empty, but with a continuation token; repeat the query w/ the token.
tryQueryAndDelete(responseOptions.continuation);
} else {
// Else if there are no more documents and no continuation token - we are finished deleting documents.
responseBody.continuation = false;
response.setBody(responseBody);
}
});
// If we hit execution bounds - return continuation: true.
if (!isAccepted) {
response.setBody(responseBody);
}
}
// Recursively deletes documents passed in as an array argument.
// Attempts to query for more on empty array.
function tryDelete(documents) {
if (documents.length > 0) {
// Delete the first document in the array.
var isAccepted = collection.deleteDocument(documents[0]._self, {}, function (err, responseOptions) {
if (err) throw err;
responseBody.deleted ;
documents.shift();
// Delete the next document in the array.
tryDelete(documents);
});
// If we hit execution bounds - return continuation: true.
if (!isAccepted) {
response.setBody(responseBody);
}
} else {
// If the document array is empty, query for more documents.
tryQueryAndDelete();
}
}
Azure function:
[FunctionName("Function1")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
[CosmosDB(
databaseName: "dbName",
collectionName: "collectionName",
ConnectionStringSetting = "CosmosDbConnectionString")]IAsyncCollector<dynamic> documentsOut,
ILogger log)
{
try
{
log.LogInformation("C# HTTP trigger function processed a request.");
string endpoint = "https://account.documents.azure.com:443/";
string key = "gixxxx==";
var client = new DocumentClient(new Uri(endpoint), key);
Uri uri = UriFactory.CreateStoredProcedureUri("service-order", "ServiceOrder", "deleteStoreSample");
RequestOptions options = new RequestOptions { PartitionKey = new PartitionKey("/id") };
var result = await client.ExecuteStoredProcedureAsync<string>(uri, options);
var response = result.Response;
return new OkObjectResult(response);
}
catch (Exception ex)
{
throw ex;
}
}
CodePudding user response:
I believe the issue is with the following line of code:
RequestOptions options = new RequestOptions { PartitionKey = new PartitionKey("/id") };
You actually need to specify the value of the partition key here and not the attribute name.
Please try changing it to something like:
RequestOptions options = new RequestOptions { PartitionKey = new PartitionKey("partition-key-value") };// Replace "partition-key-value" with actual value