internal static async Task <TableBatchResult> TableBatchOperationPostProcessAsync(TableBatchResult result, TableBatchOperation batch, RESTCommand <TableBatchResult> cmd, HttpResponseMessage resp, OperationContext ctx, TableRequestOptions options, string accountName, CancellationToken cancellationToken) { Stream responseStream = cmd.ResponseStream; StreamReader streamReader = new StreamReader(responseStream); await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); string currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); int index = 0; bool failError = false; while (currentLine3 != null && !currentLine3.StartsWith("--batchresponse")) { while (!currentLine3.StartsWith("HTTP")) { currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); } int statusCode = int.Parse(currentLine3.Substring(9, 3)); Dictionary <string, string> headers = new Dictionary <string, string>(); currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); while (!string.IsNullOrWhiteSpace(currentLine3)) { int num = currentLine3.IndexOf(':'); headers[currentLine3.Substring(0, num)] = currentLine3.Substring(num + 2); currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); } MemoryStream bodyStream = null; currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); if (statusCode != 204) { bodyStream = new MemoryStream(Encoding.UTF8.GetBytes(currentLine3)); } await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); currentLine3 = await streamReader.ReadLineAsync().ConfigureAwait(continueOnCapturedContext: false); TableOperation tableOperation = batch[index]; TableResult obj = new TableResult { Result = tableOperation.Entity }; result.Add(obj); string arg = null; if (headers.ContainsKey("Content-Type")) { arg = headers["Content-Type"]; } obj.HttpStatusCode = statusCode; bool flag; if (tableOperation.OperationType == TableOperationType.Insert) { failError = (statusCode == 409); flag = ((!tableOperation.EchoContent) ? (statusCode != 204) : (statusCode != 201)); } else if (tableOperation.OperationType == TableOperationType.Retrieve) { if (statusCode == 404) { index++; continue; } flag = (statusCode != 200); } else { failError = (statusCode == 404); flag = (statusCode != 204); } if (failError) { if (cmd.ParseErrorAsync != null) { cmd.CurrentResult.ExtendedErrorInformation = cmd.ParseErrorAsync(bodyStream, resp, arg, CancellationToken.None).Result; } cmd.CurrentResult.HttpStatusCode = statusCode; if (!string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) { string errorMessage = cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage; cmd.CurrentResult.HttpStatusMessage = errorMessage.Substring(0, errorMessage.IndexOf("\n", StringComparison.Ordinal)); } else { cmd.CurrentResult.HttpStatusMessage = statusCode.ToString(CultureInfo.InvariantCulture); } throw new StorageException(cmd.CurrentResult, (cmd.CurrentResult.ExtendedErrorInformation != null) ? cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage : "An unknown error has occurred, extended error information not available.", null) { IsRetryable = false }; } if (flag) { if (cmd.ParseErrorAsync != null) { cmd.CurrentResult.ExtendedErrorInformation = cmd.ParseErrorAsync(bodyStream, resp, arg, CancellationToken.None).Result; } cmd.CurrentResult.HttpStatusCode = statusCode; if (!string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) { string errorMessage2 = cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage; cmd.CurrentResult.HttpStatusMessage = errorMessage2.Substring(0, errorMessage2.IndexOf("\n", StringComparison.Ordinal)); } else { cmd.CurrentResult.HttpStatusMessage = statusCode.ToString(CultureInfo.InvariantCulture); } string arg2 = Convert.ToString(index, CultureInfo.InvariantCulture); if (cmd.CurrentResult.ExtendedErrorInformation != null && !string.IsNullOrEmpty(cmd.CurrentResult.ExtendedErrorInformation.ErrorMessage)) { string text = ExtractEntityIndexFromExtendedErrorInformation(cmd.CurrentResult); if (!string.IsNullOrEmpty(text)) { arg2 = text; } } throw new StorageException(cmd.CurrentResult, string.Format(CultureInfo.CurrentCulture, "Element {0} in the batch returned an unexpected response code.", arg2), null) { IsRetryable = true }; } if (headers.ContainsKey("ETag") && !string.IsNullOrEmpty(headers["ETag"])) { obj.Etag = headers["ETag"]; if (tableOperation.Entity != null) { tableOperation.Entity.ETag = obj.Etag; } } if (tableOperation.OperationType == TableOperationType.Retrieve || (tableOperation.OperationType == TableOperationType.Insert && tableOperation.EchoContent)) { if (!headers["Content-Type"].Contains("application/json;odata=nometadata")) { await ReadOdataEntityAsync(obj, tableOperation, bodyStream, ctx, accountName, options, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } else { await ReadEntityUsingJsonParserAsync(obj, tableOperation, bodyStream, ctx, options, cancellationToken).ConfigureAwait(continueOnCapturedContext: false); } } else if (tableOperation.OperationType == TableOperationType.Insert) { tableOperation.Entity.Timestamp = ParseETagForTimestamp(obj.Etag); } index++; } return(result); }
internal static async Task <TResult> ExecuteBatchOperationAsync <TResult>(TableBatchOperation batch, CloudTableClient client, CloudTable table, TableRequestOptions requestOptions, OperationContext operationContext, CancellationToken cancellationToken) where TResult : class { TableOperationType currentOperationType = batch.First().OperationType; batch.First(); try { List <Document> list = new List <Document>(); List <TableOperationType> list2 = new List <TableOperationType>(); List <string> list3 = new List <string>(); foreach (TableOperation item2 in batch) { currentOperationType = item2.OperationType; Document item = (item2.OperationType != TableOperationType.Retrieve) ? EntityHelpers.GetDocumentFromEntity(item2.Entity, operationContext, requestOptions) : EntityTranslator.GetDocumentWithPartitionAndRowKey(item2.RetrievePartitionKey, item2.RetrieveRowKey); list.Add(item); list2.Add(item2.OperationType); list3.Add((item2.Entity == null) ? string.Empty : EtagHelper.ConvertToBackEndETagFormat(item2.Entity.ETag)); } RequestOptions requestOptions2 = GetRequestOptions(batch.batchPartitionKey, requestOptions); Uri storedProcedureUri = UriFactory.CreateStoredProcedureUri("TablesDB", table.Name, "__.sys.tablesBatchOperation"); StoredProcedureResponse <string> storedProcedureResponse = await table.ServiceClient.DocumentClient.ExecuteStoredProcedureAsync <string>(storedProcedureUri, requestOptions2, new object[3] { list.ToArray(), list2.ToArray(), list3.ToArray() }); JArray jArray = JArray.Parse(storedProcedureResponse.Response); TableBatchResult tableBatchResult = new TableBatchResult(); tableBatchResult.RequestCharge = storedProcedureResponse.RequestCharge; for (int i = 0; i < jArray.Count; i++) { tableBatchResult.Add(GetTableResultFromDocument(batch[i], jArray[i].ToObject <Document>(), operationContext, requestOptions, storedProcedureResponse.SessionToken, 0.0)); } return(tableBatchResult as TResult); } catch (Exception ex) { DocumentClientException ex2 = ex as DocumentClientException; if (ex2 != null && ex2.StatusCode == HttpStatusCode.BadRequest && ex2.Message.Contains("Resource Not Found") && currentOperationType == TableOperationType.Retrieve) { TableBatchResult tableBatchResult2 = new TableBatchResult(); tableBatchResult2.Add(new TableResult { Etag = null, HttpStatusCode = 404, Result = null }); tableBatchResult2.RequestCharge = ex2.RequestCharge; return(tableBatchResult2 as TResult); } TableErrorResult tableErrorResult = ex.TranslateDocumentErrorForStoredProcs(null, batch.Count); RequestResult requestResult = GenerateRequestResult(tableErrorResult.ExtendedErroMessage, tableErrorResult.HttpStatusCode, tableErrorResult.ExtendedErrorCode, tableErrorResult.ExtendedErroMessage, tableErrorResult.ServiceRequestID, tableErrorResult.RequestCharge); StorageException ex3 = new StorageException(requestResult, requestResult.ExtendedErrorInformation.ErrorMessage, ex); if (ex2 != null) { PopulateOperationContextForBatchOperations(operationContext, ex3, ex2.ActivityId); } throw ex3; } }