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);
        }
コード例 #2
0
        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;
            }
        }