137 votes

Azure table storage renvoie 400 Bad Request

Je l'ai exécuté en mode débogage, et je joins une image avec les détails de l'exception. Comment puis-je savoir ce qui a mal tourné ? J'essayais d'insérer des données dans un tableau. Azure ne peut pas me donner plus de détails ?

Obs : Le stockage est sur Windows Azure et non sur ma machine. Les tables ont été créées, mais j'obtiens cette erreur lors de l'insertion de données

enter image description here

// 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();

et voici le code d'insertion :

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);
    }
}

178voto

Gaurav Mantri Points 19423

L'erreur 400 signifie qu'il y a un problème avec la valeur de l'une de vos propriétés. Une façon de le savoir est de suivre la demande/réponse via Fiddler et de voir les données réelles envoyées à Windows Azure Storage.

Je suppose, en jetant un coup d'œil rapide à votre code, que dans votre modèle vous avez des propriétés de type Date/Temps (OfflineTimestamp, OnlineTimestamp) et j'ai observé que dans certains scénarios l'une d'entre elles est initialisée avec la valeur par défaut qui est " DateTime.MinValue ". Veuillez noter que le La valeur minimale autorisée pour un attribut de type Date/Temps est le 1er janvier 1601 (UTC). dans Windows Azure [http://msdn.microsoft.com/en-us/library/windowsazure/dd179338.aspx] . Voyez si ce n'est pas le cas. Si c'est le cas, vous pourriez en faire des champs de type nullable afin qu'ils ne soient pas remplis avec les valeurs par défaut.

Jetez également un œil à la réponse de Juha Palomäki ci-dessous... il y a parfois un message un peu plus utile dans l'exception où il suggère (RequestInformation.ExtendedErrorInformation.ErrorMessage)

150voto

Juha Palomäki Points 7216

L'exception StorageException contient également des informations un peu plus détaillées sur l'erreur.

Vérifier dans le débogueur : StorageException.RequestInformation.ExtendedInformation

enter image description here

7voto

Nibras Manna Points 61

J'ai rencontré le même problème, mais dans mon cas, la raison était la taille. Après avoir creusé dans les propriétés d'exception supplémentaires (RequestInformation.ExtendedErrorInformation), j'ai trouvé la raison :

ErrorCode : PropertyValueTooLarge ErrorMessage : La valeur de la propriété dépasse la taille maximale autorisée (64KB). Si la valeur de la propriété est une chaîne de caractères, elle est codée en UTF-16 et le nombre maximal de caractères doit être inférieur ou égal à 32K.

5voto

Jawand Singh Points 517

Dans mon cas, j'ai essayé de faire ça :

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

à cause de ContainerName SessionMaterials (par habitude d'écrire en Pascal Case et Camel Case :D) cela provoquait 400 mauvaises requêtes. Donc, je dois juste le faire sessionmaterials . et ça a marché.

J'espère que cela aidera quelqu'un.

PS:- Vérifiez simplement l'exception de la réponse http ou utilisez fiddler pour capturer la demande et la réponse.

3voto

Maroine Abdellah Points 125

Parfois, c'est parce que votre partitionKey ou rowKey es NULL

(c'était le cas pour moi)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X