c# azure exception azure-table-storage

c# - El almacenamiento de tabla Azure devuelve 400 Bad Request



exception azure-table-storage (12)

400 Error significa que hay algo mal con el valor de una de sus propiedades. Una forma de averiguarlo es rastrear la solicitud / respuesta a través de Fiddler y ver los datos reales que se envían a Windows Azure Storage.

Asumiendo una suposición, supongo que echando un rápido vistazo a su código, en su modelo tiene algunas propiedades de tipo Fecha / Hora (OfflineTimestamp, OnlineTimestamp) y observó que en ciertos escenarios uno de ellos se inicializa con el valor predeterminado que es " DateTime.MinValue ". Tenga en cuenta que el valor mínimo permitido para un atributo de tipo Fecha / Hora es el 1 de enero de 1601 (UTC) en Windows Azure [http://msdn.microsoft.com/en-us/library/windowsazure/dd179338.aspx] . Por favor, mira si ese no es el caso. Si ese es el caso, puede hacer que sean campos de tipo anulables para que no se llenen con los valores predeterminados.

Eche un vistazo a la respuesta de Juha Palomäki a continuación ... a veces hay un mensaje un poco más útil en la excepción donde sugiere (RequestInformation.ExtendedErrorInformation.ErrorMessage)

Ejecuté esto en modo de depuración y adjunto una imagen con los detalles de la excepción. ¿Cómo puedo saber qué salió mal? Intentaba insertar datos en una tabla. ¿No puede azure darme más detalles?

Obs: el almacenamiento está en Windows Azure no en mi máquina. Las tablas fueron creadas, pero obtengo este error al insertar datos

// Retrieve the storage account from the connection string. Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=***;AccountKey=***"); // Create the table client. CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); // Create the table if it doesn''t exist. CloudTable table = tableClient.GetTableReference("EmployeeOnlineHistory"); table.CreateIfNotExists();

y aquí está el código de inserción:

public static void SetStatus(Employee e, bool value) { try { // Retrieve the storage account from the connection string. Microsoft.WindowsAzure.Storage.CloudStorageAccount storageAccount = Microsoft.WindowsAzure.Storage.CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=###;AccountKey=###"); // Create the table client. CloudTableClient tableClient = storageAccount.CreateCloudTableClient(); // Create the CloudTable object that represents the "people" table. CloudTable table = tableClient.GetTableReference("EmployeeOnlineHistory"); // Create a new customer entity. if (value == true) { EmployeeOnlineHistory empHistory = new EmployeeOnlineHistory(e.Id); empHistory.IsOnline = true; empHistory.OnlineTimestamp = DateTime.Now; TableOperation insertOperation = TableOperation.Insert(empHistory); table.Execute(insertOperation); } else { TableQuery<EmployeeOnlineHistory> query = new TableQuery<EmployeeOnlineHistory>() .Where(TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, e.Id.ToString())); EmployeeOnlineHistory entity = table.ExecuteQuery(query).Take(1).FirstOrDefault(); if ((entity!=null)&&(entity.IsOnline)) { entity.IsOnline = false; entity.OfflineTimestamp = DateTime.Now; entity.OnlineTime = (entity.OfflineTimestamp - entity.OnlineTimestamp); TableOperation updateOperation = TableOperation.Replace(entity); table.Execute(updateOperation); } else { EmployeeOnlineHistory empHistory = new EmployeeOnlineHistory(e.Id); empHistory.IsOnline = false; empHistory.OfflineTimestamp = DateTime.Now; TableOperation insertOperation = TableOperation.Insert(empHistory); table.Execute(insertOperation); } } } catch (Exception ex) { //var details = new System.IO.StreamReader(((Microsoft.WindowsAzure.Storage.StorageException)ex)..Response.GetResponseStream()).ReadToEnd(); LogFile.Error("EmployeeOnlineHistory.setStatus",ex); } }


A veces es porque tu partitionKey o rowKey es NULL

(fue el caso para mí)


En mi caso, fue una barra inclinada en RowKey .

También recibí una ''OutOfRangeInput: una de las entradas de solicitud está fuera de rango''. error al intentar agregar manualmente a través del emulador de almacenamiento.

Caracteres no permitidos en campos clave

Los siguientes caracteres no están permitidos en los valores de las propiedades PartitionKey y RowKey :

  • El carácter de barra diagonal ( / )
  • El carácter de barra invertida ( / )
  • El caracter del signo numérico ( # )
  • El carácter de interrogación ( ? )
  • Controle los caracteres de U + 0000 a U + 001F , incluidos:
    • El carácter de tabulación horizontal ( / t )
    • El carácter de salto de línea ( / n )
    • El carácter de retorno de carro ( / r )
    • Controle los caracteres de U + 007F a U + 009F

http://msdn.microsoft.com/en-us/library/dd179338.aspx

Escribí un método de extensión para manejar esto por mí.

public static string ToAzureKeyString(this string str) { var sb = new StringBuilder(); foreach (var c in str .Where(c => c != ''/'' && c != ''//' && c != ''#'' && c != ''/'' && c != ''?'' && !char.IsControl(c))) sb.Append(c); return sb.ToString(); }


Me enfrenté al mismo problema pero la razón en mi caso se debió al tamaño. Después de profundizar en las propiedades de excepción adicionales (RequestInformation.ExtendedErrorInformation), encontró el motivo:

ErrorCode: PropertyValueTooLarge ErrorMessage: el valor de la propiedad supera el tamaño máximo permitido (64 KB). Si el valor de la propiedad es una cadena, está codificada en UTF-16 y la cantidad máxima de caracteres debe ser de 32K o menos.


Obtenía una (400) Solicitud incorrecta, StatusMessage: Bad Request, ErrorCode: OutOfRangeInput cuando la entidad tenía una propiedad DateTime no configurada (= DateTime.MinValue)


Puede encontrar una documentación de MS sobre todos los códigos de error de servicio de tabla here


Recibía una Solicitud incorrecta 400 porque estaba usando ZRS (almacenamiento redundante de zona) y Analytics no está disponible para este tipo de almacenamiento. No sabía que estaba usando Analytics.

Eliminé el contenedor de almacenamiento y recreé como GRS y ahora funciona bien.


Solucioné mis casos y funcionó bien

Mis casos:

  1. La clave de fila no está en el formato correcto (400).
  2. La combinación de partitionkey y rowkey no es única (409).

StorageException también contiene información un poco más detallada sobre el error.

Check in depurador: StorageException.RequestInformation.ExtendedInformation


También me enfrenté al mismo tipo de problema. En mi caso, el valor de PartitionKey no estaba establecido, por lo que el valor predeterminado de PartitionKey era nulo, lo que dio como resultado que la Object reference not set to an instance of an object. excepción

Compruebe si está proporcionando los valores adecuados para PartitionKey o RowKey, puede enfrentar tal problema.


bueno, en mi caso yo estaba tratando de hacer esto:

CloudBlobContainer container = blobClient.GetContainerReference("SessionMaterials"); await container.CreateIfNotExistsAsync();

debido a ContainerName SessionMaterials estaba causando 400 solicitudes incorrectas. Entonces, solo tengo que hacerlo en los materiales de sessionmaterials . Y funcionó.

Espero que esto ayude a alguien.

PD: - Solo verifique la respuesta http de excepción o use el violín para capturar la solicitud y la respuesta.


en mi caso: el nombre del contenedor estaba en mayúscula. hay limitaciones al usar caracteres.