Penyimpanan tabel Azure mengembalikan 400 Permintaan Buruk


119

Saya menjalankan ini dalam mode debug, dan saya melampirkan gambar dengan detail pengecualian. Bagaimana saya bisa tahu apa yang salah? Saya mencoba memasukkan data ke dalam tabel. Tidak bisakah biru memberi saya detail lebih lanjut?

Obs: Penyimpanan ada di Windows Azure bukan di komputer saya. Tabel dibuat, tetapi saya mendapatkan kesalahan ini saat memasukkan data

masukkan deskripsi gambar di sini

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

dan ini kode sisipannya:

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

Gambar itu tidak terlalu membantu, selain dari mengkonfirmasi kesalahan 400. Akankah "membantu" adalah menunjukkan kode yang Anda jalankan yang mengakibatkan permintaan buruk: bagaimana Anda mengatur klien penyimpanan, bagaimana Anda mengatur tabel, lalu pergi untuk memasukkan, dll.
David Makogon

Saya menyalin-tempel kode. Semoga ini bisa membantu
Ryan

Akan membantu jika Anda mengatakan yang mana dari beberapa kasus yang gagal. Juga, Anda tampaknya menyetel beberapa properti di luar kode ini (mis., PartitionKey dan RowKey) sehingga akan membantu untuk mengetahui apa itu dan apa yang mereka atur.
Brian Reischl

Saya perhatikan bahwa ketika Exception dilemparkan terlebih dahulu, tidak ada opsi "View Detail" tetapi ketika Anda melanjutkan debugging dan aliran kembali ke pemanggil (di mana pengecualian muncul lagi), Anda dapat melihat opsi View Detail. Dari sana Anda dapat menggunakan jawaban @Juha Palomäki untuk menemukan kesalahannya
raghav710

Jawaban:


148

400 Error berarti ada yang salah dengan nilai salah satu properti Anda. Salah satu cara untuk mengetahuinya adalah dengan melacak permintaan / respons melalui Fiddler dan melihat data aktual yang dikirim ke Windows Azure Storage.

Mengambil tebakan liar, saya berasumsi dengan melihat sekilas kode Anda bahwa dalam model Anda, Anda memiliki beberapa properti tipe Tanggal / Waktu (OfflineTimestamp, OnlineTimestamp) dan mengamati bahwa dalam skenario tertentu salah satunya diinisialisasi dengan nilai default yang adalah " DateTime.MinValue ". Harap dicatat bahwa nilai minimum yang diperbolehkan untuk atribut tipe Tanggal / Waktu adalah 1 Jan 1601 (UTC) di Windows Azure [http://msdn.microsoft.com/en-us/library/windowsazure/dd179338.aspx] . Silakan lihat apakah bukan itu masalahnya. Jika demikian, maka Anda bisa menjadikannya bidang tipe nullable sehingga tidak diisi dengan nilai default.

Lihatlah jawaban Juha Palomäki di bawah ini juga ... terkadang ada pesan yang sedikit lebih berguna dalam pengecualian yang dia sarankan (RequestInformation.ExtendedErrorInformation.ErrorMessage)


259
Demi Tuhan, jika seseorang dari tim Azure membaca ini, harap buat SDK mengembalikan lebih banyak informasi daripada kesalahan 400 Permintaan Buruk. Saya tidak tahu mengapa DateTime dalam penyimpanan tabel tidak dapat memiliki tanggal minimum yang sama dengan objek .NET DateTime, tetapi saya menyia-nyiakan hari yang baik untuk yang satu ini. Pada saat saya mengetahui properti mana yang menyebabkan masalah, saya juga menemukan hal ini, yang membantu. Sekarang, sebelum saya memasukkan / memperbarui model dengan DateTime untuk penyimpanan tabel, saya harus menjalankan pemeriksaan pada semua properti DateTime. TIDAK ideal ...
Michael

8
Saat kami melakukannya, Anda juga tidak dapat memiliki properti enum. Saya harus mengubah properti menjadi Integer
Martin

15
Rupanya, nama tabel juga tidak boleh memiliki tanda hubung. Butuh waktu satu jam untuk mencari tahu.
Amogh Natu

4
Nama tabel juga tidak boleh memiliki garis bawah .. itulah sebabnya saya ada di sini
Quango

2
Saya membayangkan RowKey tidak dimulai dengan string kosong karena ini adalah nilai pencarian utama dan hanya kolom yang diindeks ... ini untuk mengingatkan Anda untuk mengisinya, saya akan berpikir .... ini hanya tebakan saya ... Sejauh ini nama tabel pergi .. memiliki membaca ini ... blogs.msdn.microsoft.com/jmstall/2014/06/12/...
dreadeddev

129

StorageException juga berisi informasi yang sedikit lebih detail tentang kesalahan.

Periksa di debugger: StorageException.RequestInformation.ExtendedInformation

masukkan deskripsi gambar di sini


6
Mengapa informasi ini bukan pengecualian tingkat atas?
Wilko van der Veen

Bagi saya ini disorot .. "Tambahkan blob yang tidak didukung oleh emulator" .. FML
Michiel Cornille

The specifed resource name contains invalid characters.nama meja saya memiliki tanda hubung di dalamnya ... seperti nama antrian saya ... huh. Semoga pencarian mengambil ini untuk lebih banyak orang! lihat: stackoverflow.com/questions/45305556/…
Nateous

55

Dalam kasus saya, itu adalah garis miring di RowKey .

Saya juga menerima 'OutOfRangeInput - Salah satu input permintaan di luar jangkauan.' error saat mencoba menambahkan secara manual melalui emulator penyimpanan.

Karakter Dilarang dalam Bidang Kunci

Karakter berikut ini tidak diperbolehkan dalam nilai untuk properti PartitionKey dan RowKey :

  • Karakter garis miring ( / )
  • Karakter garis miring terbalik ( \ )
  • Karakter tanda nomor ( # )
  • Karakter tanda tanya ( ? )
  • Kontrol karakter dari U + 0000 hingga U + 001F , termasuk:
    • Karakter tab horizontal ( \ t )
    • Karakter linefeed ( \ n )
    • Karakter carriage return ( \ r )
    • Kontrol karakter dari U + 007F hingga U + 009F

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

Saya menulis metode ekstensi untuk menangani ini untuk saya.

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

4
Ini juga masalah saya. Metode ekstensi Anda berfungsi seperti juara!
James Wilson

1
Saya menyukai Metode Ekstensi. Menyelamatkan saya.
Newton Sheikh

Tanggapan alternatif diberikan di sini yang menggantikan regex stackoverflow.com/a/28788382/285795
ΩmegaMan

Memperbaiki itu untuk saya. Saya memiliki garis miring ke depan. Tampak seperti karakter yang bagus untuk kunci gabungan semu.
richard

Metode ekstensi ini tidak menghapus beberapa karakter yang tidak diperbolehkan. Misalnya: spasi, "(", ")" ... docs.microsoft.com/en-us/rest/api/storageservices/…
Tiago Andrade e Silva

6

Saya menghadapi masalah yang sama tetapi alasan dalam kasus saya adalah karena ukuran. Setelah menggali properti pengecualian tambahan (RequestInformation.ExtendedErrorInformation), temukan alasannya:

ErrorCode: PropertyValueTooLarge ErrorMessage: Nilai properti melebihi ukuran maksimum yang diperbolehkan (64KB). Jika nilai properti adalah string, itu adalah UTF-16 dan jumlah karakter maksimum harus 32K atau kurang.


5

baik, dalam kasus saya, saya mencoba melakukan ini:

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

karena ContainerName SessionMaterials(sebagai kebiasaan menulis di Pascal Case dan Camel Case: D) menyebabkan 400 permintaan yang buruk. Jadi, saya harus membuatnya sessionmaterials. dan itu berhasil.

Semoga ini bisa membantu seseorang.

PS: - Cukup periksa respons http pengecualian atau gunakan fiddler untuk menangkap permintaan dan respons.


3

dalam kasus saya: Nama wadah ditulis dengan huruf kapital. ada batasan saat menggunakan karakter. masukkan deskripsi gambar di sini


Ini berlaku untuk nama properti tabel juga.
Iain Ballard


1

Dokumentasi dari MS tentang semua Kode Kesalahan Layanan Tabel dapat ditemukan di sini


1

Saya mengalami Error BadRequest (400) yang sama, pada akhirnya saya isi secara manual:

masukkan deskripsi gambar di sini

Dan bekerja untuk saya. Semoga ini membantu!


Jawaban ini benar. Saya menyia-nyiakan waktu sekitar satu jam dan ternyata itu bahkan Timestampharus dibuat secara manual. Sangat menyebalkan.
Roman Koliada

0

Saya juga menghadapi masalah yang sama. Dalam kasus saya, nilai PartitionKey tidak disetel, jadi secara default nilai PartitionKey adalah null, yang mengakibatkan Object reference not set to an instance of an object.pengecualian

Periksa apakah Anda memberikan nilai yang sesuai untuk PartitionKey atau RowKey, Anda mungkin menghadapi masalah seperti itu.


0

Saya memperbaiki kasus saya dan bekerja dengan baik

Kasus saya:

  1. Format kunci baris salah (400).
  2. Kombinasi kunci partisi dan kunci baris tidak unik (409).

0

Saya mendapatkan 400 Permintaan Buruk karena saya menggunakan ZRS (Zone Redundant Storage), dan Analytics tidak tersedia untuk jenis penyimpanan ini. Saya tidak sadar saya menggunakan Analytics.

Saya menghapus wadah penyimpanan dan membuatnya kembali sebagai GRS dan sekarang berfungsi dengan baik.


0

Saya mendapatkan (400) Permintaan Buruk, StatusMessage: Permintaan Buruk, ErrorCode: OutOfRangeInput ketika entitas memiliki properti DateTime tidak disetel (= DateTime.MinValue)


0

Dalam kasus saya: Saya menyertakan metadata blob dengan nama tag yang berisi tanda hubung.

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

Tanda hubung di "added-by"masalahnya, dan kemudian RTFM memberi tahu saya bahwa nama tag harus sesuai dengan konvensi pengenal C #.

Ref: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-properties-metadata

Garis bawah berfungsi dengan baik.


0

Dalam kasus saya, saya tidak boleh menambahkan PartitionKey dan Rowkey di kelas entitas saya. Itu harus dari kelas dasar. Di bawah ini akan berhasil.

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


      public TableRunLogMessage() { }
}

0

Jika Anda menggunakan NodeJS dan menemukan posting ini, hanya untuk menemukan bahwa Anda tidak mendapatkan informasi rinci yang indah di objek kesalahan Anda; Anda dapat menggunakan proxy untuk mendapatkan detail tersebut. Namun, karena tidak ada orang di sini yang menyebutkan CARA menggunakan proxy.

Cara termudah dengan NodeJS adalah dengan menetapkan dua variabel lingkungan:

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.

Jika Anda benar-benar menggunakan C #, seperti yang dilakukan penulis posting ini; Anda cukup menginstal Fiddler dan mengaturnya ke intercept. Secara default itu harus mencegat permintaan. Anda mungkin juga perlu mempercayai sertifikat Fiddler atau melakukan hal yang setara dengan "NODE_TLS_REJECT_UNAUTHORIZED = 0" Node.


0

Saya mendapat respons 400-BadRequest dari Azure Storage Account Table API. Informasi pengecualian menunjukkan bahwa "Akun yang diakses tidak mendukung http.". Saya pikir kita harus menggunakan https dalam string koneksi ketika "Secure transfer required" diaktifkan dalam konfigurasi akun penyimpanan seperti yang ditunjukkan pada gambar di bawah ini.masukkan deskripsi gambar di sini


0

Dalam kasus saya untuk membuat instalnce baru dari kelas "TableBotDataStore" (kerangka bot MS) kami melewati parameter "tableName" dengan tanda hubung seperti "master-bot" dan TableBotDataStore hanya dapat memiliki nama tabel dengan huruf dan angka saja


0

Saya memiliki masalah yang sama, fungsinya meneruskan containerNameKeystring as. di bawah ini adalah kode yang memberikan kesalahan

container = blobClient.GetContainerReference(containerNameKey) 

Saya mengubahnya menjadi

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

Berhasil

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.