web-dev-qa-db-de.com

Azure-Tabellenspeicher gibt 400 fehlerhafte Anforderung zurück

Ich habe dies im Debug-Modus ausgeführt und füge ein Bild mit den Details der Ausnahme hinzu. Woher weiß ich, was schief gelaufen ist? Ich habe versucht, Daten in eine Tabelle einzufügen. Kann Azure mir nicht mehr Details geben?

Obs: Der Speicher befindet sich auf Windows Azure und nicht auf meinem Computer. Die Tabellen wurden erstellt, aber beim Einfügen von Daten wird diese Fehlermeldung angezeigt

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

und hier ist der Einfügungscode:

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

400 Error bedeutet, dass der Wert einer Ihrer Eigenschaften nicht stimmt. Um dies herauszufinden, können Sie die Anfrage/Antwort über Fiddler nachverfolgen und die tatsächlichen Daten sehen, die an Windows Azure Storage gesendet werden. 

Ich gehe davon aus, dass Sie in Ihrem Modell einige Date/Time-Typ-Eigenschaften (OfflineTimestamp, OnlineTimestamp) haben. In bestimmten Szenarien wurde einer davon mit dem Standardwert initialisiert ist "DateTime.MinValue". Beachten Sie, dass der Wert für minimum für ein Attribut vom Typ Datum/Zeit 1. Jan 1601 (UTC) in Windows Azure [http://msdn.Microsoft.com/en-us/library/windowsazure/) ist. dd179338.aspx] . Bitte sehen Sie, ob das nicht der Fall ist. Wenn dies der Fall ist, können Sie sie als Felder mit Nullwert definieren, damit sie nicht mit den Standardwerten gefüllt werden.

Schauen Sie sich auch die Antwort von Juha Palomäki unten an ... in der Ausnahme erscheint manchmal eine etwas nützlichere Nachricht (RequestInformation.ExtendedErrorInformation.ErrorMessage)

127
Gaurav Mantri

Die StorageException enthält auch etwas detailliertere Informationen zu Fehlern. 

Überprüfen Sie im Debugger: StorageException.RequestInformation.ExtendedInformation

enter image description here

103
Juha Palomäki

In meinem Fall war es ein Schrägstrich im RowKey

Ich habe auch ein "OutOfRangeInput - Eine der Anforderungseingaben ist außerhalb des Bereichs" erhalten. Fehler beim Versuch, manuell über den Speicheremulator hinzuzufügen.

In Schlüsselfeldern nicht zulässige Zeichen

Die folgenden Zeichen sind in Werten für die .__ nicht zulässig. PartitionKey - und RowKey - Eigenschaften:

  • Der Schrägstrich (/)
  • Der umgekehrte Schrägstrich (\)
  • Das Nummernzeichen (#)
  • Das Fragezeichen (?)
  • Steuerzeichen von U + 0000 bis U + 001F, einschließlich:
    • Das horizontale Tabulatorzeichen (\ t)
    • Das Zeilenvorschubzeichen (\ n)
    • Das Wagenrücklaufzeichen (\ r)
    • Steuerzeichen von U + 007F bis U + 009F

http://msdn.Microsoft.com/de-de/library/dd179338.aspx

Ich habe eine Erweiterungsmethode geschrieben, um dies für mich zu erledigen .

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();
}
44
Shawn

nun, in meinem Fall habe ich versucht, das zu tun:

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

wegen ContainerName SessionMaterials (als Gewohnheitsschreiben in Pascal Case und Camel Case: D) wurden 400 fehlerhafte Anforderungen verursacht. Also, ich muss es nur sessionmaterials..__ machen und es hat funktioniert.

Hoffe das hilft jemandem. 

PS: - Überprüfen Sie die HTTP-Antwort der Ausnahme oder verwenden Sie den Fiddler, um die Anforderung und die Antwort zu erfassen.

3
Jawand Singh

Ich war mit dem gleichen Problem konfrontiert, aber der Grund in meinem Fall lag in der Größe. Nachdem Sie die zusätzlichen Ausnahmeeigenschaften (RequestInformation.ExtendedErrorInformation) durchsucht haben, wurde der Grund gefunden: 

ErrorCode: PropertyValueTooLarge ErrorMessage: Der Eigenschaftswert überschreitet die maximal zulässige Größe (64 KB). Wenn der Eigenschaftswert eine Zeichenfolge ist, ist er UTF-16-codiert. Die maximale Anzahl an Zeichen sollte 32 KB oder weniger betragen.

3
Nibras Manna

Manchmal liegt es daran, dass Ihre partitionKey oder rowKeyNULL ist.

(es war der Fall für mich)

3

in meinem Fall : Containername war in Großbuchstaben. Bei der Verwendung von Zeichen gibt es Einschränkungen.  enter image description here

3
Ravi Anand

Ich hatte den gleichen BadRequest (400) Error, am Ende fülle ich manuell aus:

 enter image description here

Und arbeitete für mich. Hoffe das hilft!

1
gatsby

Eine Dokumentation von MS über alle Table Service Error-Codes finden Sie hier

1
huha

In meinem Fall sollte ich PartitionKey und Rowkey nicht zu meiner Entitätsklasse hinzufügen. Es sollte aus der Basisklasse stammen. Unten würde nur funktionieren.

public class TableRunLogMessage:TableEntity
{
      public string status { get; set; }
      public long logged { get; set; }


      public TableRunLogMessage() { }
}
0
merry

Ich erhielt eine (400) ungültige Anforderung, StatusMessage: Fehlerhafte Anforderung, Fehlercode: OutOfRangeInput, wenn die Entität eine Eigenschaft DateTime nicht festgelegt hatte (= DateTime.MinValue).

0
Stig

Ich hatte auch ein ähnliches Problem. In meinem Fall wurde der PartitionKey-Wert nicht festgelegt, daher war der PartitionKey-Wert standardmäßig null, was zu einer Object reference not set to an instance of an object.-Ausnahme führte

Überprüfen Sie, ob Sie die entsprechenden Werte für PartitionKey oder RowKey angeben. Dieses Problem kann auftreten.

0
Dilip Nannaware

Ich habe eine 400-Fehler-Anforderung erhalten, weil ich ZRS (Zone Redundant Storage) verwendet habe und Analytics für diese Art von Speicher nicht verfügbar ist. Ich wusste nicht, dass ich Analytics verwendete. 

Ich habe den Speichercontainer gelöscht und als GRS neu erstellt, und jetzt funktioniert es einwandfrei.

0
Aidan

Ich hatte das gleiche Problem, die Funktion übergab die containerNameKey als Zeichenfolge. unten ist der Code, der Fehler gab

container = blobClient.GetContainerReference(containerNameKey) 

Ich habe es in geändert

container = blobClient.GetContainerReference(ConfigurationManager.AppSettings(containerNameKey).ToString()) 

Es funktionierte

0
Vani

In meinem Fall zum Erstellen einer neuen Instanz der "TableBotDataStore" -Klasse (MS-Bot-Framework) übergeben wir den Parameter "tableName" mit einem Bindestrich wie "master-bot", und TableBotDataStore kann Tabellennamen nur mit Buchstaben und Zahlen haben

0
igor_bugaenko

In meinem Fall: Ich habe Blob-Metadaten mit einem Tag-Namen mit einem Bindestrich eingefügt.

var blob = container.GetBlockBlobReference(filename);
blob.Metadata.Add("added-by", Environment.UserName);
//.. other metadata
blob.UploadFromStream(filestream);

Der Strich in "added-by" war das Problem, und später RTFM wurde mir mitgeteilt, dass Tag-Namen den C # -Kennungskonventionen entsprechen müssen.

Ref: https://docs.Microsoft.com/de-de/Azure/storage/blobs/storage-properties-metadata

Unterstreichung funktioniert gut.

0
Steve Friedl

Ich habe eine 400-BadRequest-Antwort von der Azure Storage Account Table-API erhalten. Ausnahmeinformationen zeigten, dass "das Konto, auf das zugegriffen wird, http nicht unterstützt". Ich stellte fest, dass wir in der Verbindungszeichenfolge https verwenden müssen, wenn "Sichere Übertragung erforderlich" in der Speicherkontokonfiguration aktiviert ist (siehe Abbildung unten) . enter image description here

0
Kalaiselvan

Wenn Sie NodeJS verwenden und auf diesen Beitrag gestoßen sind, müssen Sie feststellen, dass Sie diese schönen detaillierten Informationen nicht in Ihrem Fehlerobjekt erhalten. Sie können einen Proxy verwenden, um diese Details zu erhalten. Da hier jedoch niemand erwähnt wird, wie ein Proxy verwendet wird.

Der einfachste Weg mit NodeJS ist das Setzen von zwei Umgebungsvariablen:

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.

Wenn Sie tatsächlich C # verwenden, wie es der Autor dieses Posts tut; Sie können Fiddler einfach installieren und auf Abfangen einstellen. Standardmäßig sollte er die Anforderungen abfangen. Sie müssen möglicherweise auch dem Zertifikat von Fiddler vertrauen oder auf andere Weise das Äquivalent von "NODE_TLS_REJECT_UNAUTHORIZED = 0" des Knotens ausführen.

0
Doug

Ich habe meine Fälle repariert und es hat gut funktioniert

Meine Fälle:

  1. Zeilenschlüssel hat nicht das richtige Format (400).
  2. Kombination aus Partitionsschlüssel und Reihenschlüssel ist nicht eindeutig (409).
0
Kurkula