J'ai exécuté cela en mode débogage et je joint une image avec les détails de l'exception. Comment puis-je savoir ce qui s'est mal passé? J'essayais d'insérer des données dans une table. Azure ne peut-il pas me donner plus de détails?
Obs: Le stockage est sur Windows Azure pas sur ma machine. Les tables ont été créées, mais j'obtiens cette erreur lors de l'insertion de données
// 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);
}
}
400 Erreur 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 consiste à suivre la demande/réponse via Fiddler et à voir les données réelles envoyées à Windows Azure Storage.
Prenant une conjecture sauvage, je suppose en jetant un coup d'œil sur votre code que dans votre modèle, vous avez des propriétés de type Date/Heure (OfflineTimestamp, OnlineTimestamp) et que, dans certains scénarios, l'un d'entre eux est initialisé avec la valeur par défaut qui est "DateTime.MinValue". Notez que la valeur minimale de autorisée pour un attribut de type Date/Heure est le 1er janvier 1601 (UTC) dans Windows Azure [http://msdn.Microsoft.com/en-us/library/windowsazure/ dd179338.aspx] . S'il vous plaît voir si ce n'est pas le cas. Si tel est le cas, vous pouvez alors définir des champs de type Nullable afin qu'ils ne soient pas renseignés avec les valeurs par défaut.
Regardez aussi la réponse ci-dessous de Juha Palomäki ... il existe parfois un message légèrement plus utile dans l'exception où il suggère (RequestInformation.ExtendedErrorInformation.ErrorMessage)
StorageException contient également des informations un peu plus détaillées sur les erreurs.
Archiver dans le débogueur: StorageException.RequestInformation.ExtendedInformation
Dans mon cas, il s'agissait d'une barre oblique dans RowKey.
J'ai également reçu un message 'OutOfRangeInput - Une des entrées de la demande est hors limites.' erreur en essayant d'ajouter manuellement via l'émulateur de stockage.
Caractères non autorisés dans les champs clés
Les caractères suivants ne sont pas autorisés dans les valeurs pour le Propriétés PartitionKey et RowKey:
- La barre oblique (/)
- La barre oblique inverse (\)
- Le signe dièse (#)
- Le point d'interrogation (?) Caractère
- Caractères de contrôle de U + 0000 à U + 001F, y compris:
- Le caractère de tabulation horizontale (\ t)
- Le saut de ligne (\ n) caractère
- Le caractère de retour chariot (\ r)
- Caractères de contrôle de U + 007F à U + 009F
http://msdn.Microsoft.com/en-us/library/dd179338.aspx
J'ai écrit une méthode d'extension pour gérer cela pour moi .
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();
}
eh bien, dans mon cas, j'essayais de faire ceci:
CloudBlobContainer container = blobClient.GetContainerReference("SessionMaterials");
await container.CreateIfNotExistsAsync();
à cause de ContainerName SessionMaterials
(comme habitude d'écrire dans Pascal Case et Camel Case: D), il causait 400 mauvaises requêtes. Donc, Je dois juste le faire sessionmaterials
. Et cela a fonctionné.
J'espère que cela aide quelqu'un.
PS: - Il suffit de vérifier la réponse HTTP d’exception ou d’utiliser Fiddler pour capturer demande et réponse.
J'ai eu le même problème mais la raison dans mon cas était due à la taille. Après avoir exploré les propriétés d'exception supplémentaires (RequestInformation.ExtendedErrorInformation), vous en avez trouvé la raison:
ErrorCode: PropertyValueTooLarge ErrorMessage: la valeur de la propriété dépasse la taille maximale autorisée (64 Ko). Si la valeur de la propriété est une chaîne, elle est codée en UTF-16 et le nombre maximal de caractères doit être inférieur ou égal à 32 Ko.
Parfois, c'est parce que votre partitionKey
ou rowKey
est NULL
(c'était le cas pour moi)
Une documentation de MS sur tous les codes d'erreur du service de table est disponible ici
Dans mon cas, je ne devrais pas ajouter PartitionKey et Rowkey dans ma classe d'entité. Il devrait être de la classe de base. Ci-dessous serait juste travailler.
public class TableRunLogMessage:TableEntity
{
public string status { get; set; }
public long logged { get; set; }
public TableRunLogMessage() { }
}
Je recevais une (400) demande incorrecte, StatusMessage: demande incorrecte, ErrorCode: OutOfRangeInput lorsque l'entité avait une propriété DateTime non définie (= DateTime.MinValue)
J'ai également rencontré le même genre de problème. Dans mon cas, la valeur PartitionKey n'était pas définie. Par défaut, la valeur PartitionKey était null, ce qui a entraîné une exception Object reference not set to an instance of an object.
Vérifiez si vous fournissez les valeurs appropriées pour PartitionKey ou RowKey, vous pouvez être confronté à un tel problème.
J'obtenais une demande 400 bad parce que j'utilisais ZRS (Zone Redundant Storage), et Analytics n'est pas disponible pour ce type de stockage. Je ne savais pas que j'utilisais Google Analytics.
J'ai supprimé le conteneur de stockage et recréé en tant que GRS et maintenant cela fonctionne bien.
J'ai eu le même problème, la fonction passait le containerNameKey
en tant que chaîne. ci-dessous est le code qui a donné une erreur
container = blobClient.GetContainerReference(containerNameKey)
Je l'ai changé pour
container = blobClient.GetContainerReference(ConfigurationManager.AppSettings(containerNameKey).ToString())
Ça a marché
Dans mon cas, pour créer une nouvelle instance de la classe "TableBotDataStore" (infrastructure MS bot), nous passons le paramètre "tableName" avec un trait d'union comme "master-bot" et TableBotDataStore peut uniquement avoir des noms de table avec des lettres et des chiffres.
Dans mon cas: j'ai inclus des métadonnées de blob avec un nom de balise contenant un trait d'union.
var blob = container.GetBlockBlobReference(filename);
blob.Metadata.Add("added-by", Environment.UserName);
//.. other metadata
blob.UploadFromStream(filestream);
Le tiret dans "added-by"
était le problème, et plus tard, RTFM m'a dit que les noms de balises doivent être conformes aux conventions d'identificateur C #.
Réf.: https://docs.Microsoft.com/en-us/Azure/storage/blobs/storage-properties-metadata
Le soulignement fonctionne bien.
J'ai reçu une réponse 400-BadRequest de l'API Azure Storage Account Table. Les informations sur les exceptions indiquent que "le compte auquel on accède ne prend pas en charge http.". J'ai pensé que nous devions utiliser https dans la chaîne de connexion lorsque "Transfert sécurisé requis" est activé dans la configuration du compte de stockage, comme indiqué dans l'image ci-dessous.
Si vous utilisez NodeJS et que vous avez trébuché sur ce post, seulement pour constater que vous n'obtenez pas cette belle information détaillée dans votre objet d'erreur; vous pouvez utiliser un proxy pour obtenir ces détails. Cependant, puisque personne n’indique ici comment utiliser un proxy.
La méthode la plus simple avec NodeJS consiste à définir deux variables d’environnement:
NODE_TLS_REJECT_UNAUTHORIZED=0
This disables SSL checks so you can intercept your own SSL requests. This leaves you open to Man-in-The-Middle attacks and should NEVER make it to production, and I wouldn't even leave it in development for long. However, it will allow you to intercept the HTTP Requests.
HTTP_PROXY=http://127.0.0.1:8888
This sets node to utilize a proxy listening on your localhost at port 8888. Port 8888 is the default for Fiddler. Many other proxies default to 8080.
Si vous utilisez réellement C #, comme le fait l'auteur de ce post; vous pouvez simplement installer Fiddler et le configurer pour l’intercepter. Par défaut, il devrait intercepter les demandes. Vous devrez peut-être également faire confiance au certificat de Fiddler ou faire l'équivalent de "NODE_TLS_REJECT_UNAUTHORIZED = 0" du noeud.
J'ai réparé mes valises et cela a bien fonctionné
Mes cas: