Azure tablo depolaması 400 Hatalı İstek döndürüyor


119

Bunu hata ayıklama modunda çalıştırdım ve istisnanın ayrıntılarını içeren bir resim ekledim. Neyin yanlış gittiğini nasıl bilebilirim? Bir tabloya veri eklemeye çalışıyordum. Azure bana daha fazla ayrıntı veremez mi?

Obs: Depolama, makinemde değil Windows Azure'da. Tablolar oluşturuldu, ancak veri eklerken bu hatayı alıyorum

görüntü açıklamasını buraya girin

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

ve işte ekleme kodu:

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

Bu resim, 400 hatasını onaylamanın yanı sıra gerçekten yardımcı olmuyor. "Olur" yardımcı olur mu, çalıştırdığınız kodu göstererek kötü istekle sonuçlanır: depolama istemcisini nasıl kurduğunuz, tabloyu nasıl kurduğunuz ve sonra gittiğiniz eklemek, vb.
David Makogon

Kodu kopyalayıp yapıştırdım. Umarım bu yardımcı olur
Ryan

Birkaç vakadan hangisinin başarısız olduğunu söylerseniz yardımcı olur. Ayrıca, görünüşe göre bu kodun dışındaki bazı özellikleri (örneğin, PartitionKey ve RowKey) ayarlıyorsunuz, böylece bunların ne olduğunu ve neye ayarlandığını bilmek yardımcı olacaktır.
Brian Reischl

İlk önce İstisna atıldığında, "Ayrıntıları Görüntüle" seçeneğinin olmadığını fark ettim, ancak hata ayıklamaya devam ettiğinizde ve akış arayana geri döndüğünde (istisnanın tekrar ortaya çıktığı yerde), Ayrıntıyı Görüntüle seçeneğini görebiliyorsunuz. Oradan, hatayı bulmak için @Juha Palomäki'nin cevabını kullanabilirsiniz
raghav710

Yanıtlar:


149

400 Hatası, mülklerinizden birinin değerinde bir sorun olduğu anlamına gelir. Bunu öğrenmenin bir yolu, isteği / yanıtı Fiddler aracılığıyla izlemek ve Windows Azure Depolama'ya gönderilen gerçek verileri görmektir.

Çılgın bir tahminde bulunarak, kodunuza hızlıca bir göz atarak, modelinizde bazı Tarih / Saat türü özelliklerine (OfflineTimestamp, OnlineTimestamp) sahip olduğunuzu ve bazı senaryolarda bunlardan birinin varsayılan değerle başlatıldığını varsayıyorum. " DateTime.MinValue " dir. Windows Azure [http://msdn.microsoft.com/en-us/library/windowsazure/dd179338.aspx] Tarih / Saat türü özniteliği için izin verilen minimum değerin 1 Ocak 1601 (UTC) olduğunu lütfen unutmayın . Lütfen durumun bu olup olmadığına bakın. Durum buysa, bunları varsayılan değerlerle doldurulmamaları için null yapılabilir tür alanları yapabilirsiniz.

Juha Palomäki'nin aşağıdaki cevabına da bir göz atın ... Bazen istisnada önerdiği yerde biraz daha faydalı bir mesaj vardır (RequestInformation.ExtendedErrorInformation.ErrorMessage)


260
Tanrı aşkına, Azure ekibinden biri bunu okursa lütfen SDK'nın 400 Kötü İstek hatasından daha fazla bilgi döndürmesini sağlayın. Tablo depolamasındaki DateTime öğesinin .NET DateTime nesnesiyle neden aynı minimum tarihe sahip olamayacağına dair hiçbir fikrim yok, ancak bunda iyi bir gün geçirdim. Soruna hangi mülkün neden olduğunu anladığımda, bununla da karşılaştım, bu da yardımcı oldu. Şimdi, tablo depolaması için DateTime içeren bir modeli eklemeden / güncellemeden önce, tüm DateTime özelliklerinde kontroller çalıştırmam gerekiyor. İdeal DEĞİL ...
Michael

8
Biz oradayken, bir enum özelliğine de sahip olamazsınız. Mülkü
Martin

15
Görünüşe göre, tablo adlarında da kısa çizgi olamaz. Bunu anlamam bir saatimi aldı.
Amogh Natu

4
Tablo adlarında da alt çizgi olamaz .. bu yüzden buradayım
Quango

2
RowKey'in boş dizeyle başlatılmadığını hayal ediyorum, çünkü bu ana arama değeri ve yalnızca dizine alınmış sütun ... bunu doldurmanızı hatırlatmak için düşünmüştüm .... bu sadece benim tahminim olsa da ... tablo adları gidin .. bunu okuyun ... blogs.msdn.microsoft.com/jmstall/2014/06/12/…
dreadeddev

129

StorageException ayrıca hata hakkında biraz daha ayrıntılı bilgi içerir.

Hata ayıklayıcıyı kontrol edin: StorageException.RequestInformation.ExtendedInformation

görüntü açıklamasını buraya girin


6
Bu bilgi neden üst düzey bir istisna değil?
Wilko van der Veen

Benim için bu vurgulanmıştır .. "Blob ekle emülatör tarafından desteklenmiyor" .. FML
Michiel Cornille

The specifed resource name contains invalid characters.masa adımda çizgiler vardı ... tıpkı sıra isimlerim gibi ... ah. Umarım arama, bunu daha fazla kişi için alır! bkz: stackoverflow.com/questions/45305556/…
Nateous,

55

Benim durumumda, RowKey'de bir eğik çizgi idi .

Ayrıca bir 'OutOfRangeInput - İstek girişlerinden biri aralık dışı' mesajı aldım. depolama öykünücüsü aracılığıyla manuel olarak eklemeye çalışırken hata.

Anahtar Alanlarda İzin Verilmeyen Karakterler

PartitionKey ve RowKey özelliklerinin değerlerinde aşağıdaki karakterlere izin verilmez :

  • Eğik çizgi ( / ) karakteri
  • Ters eğik çizgi ( \ ) karakteri
  • Sayı işareti ( # ) karakteri
  • Soru işareti ( ? ) Karakteri
  • U + 0000 ile U + 001F arasındaki kontrol karakterleri :
    • Yatay sekme ( \ t ) karakteri
    • Satır besleme ( \ n ) karakteri
    • Satır başı ( \ r ) karakteri
    • U + 007F'den U + 009F'ye kadar kontrol karakterleri

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

Bunu benim için halletmek için bir uzatma yöntemi yazdı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();
}

4
Bu benim de sorunumdu. Uzatma yönteminiz bir şampiyon gibi çalışır!
James Wilson

1
Uzatma Yöntemini sevdim. Beni kurtardı.
Newton Şeyh

Burada verilen ve bir normal ifadenin stackoverflow.com/a/28788382/285795'in
ΩmegaMan

Benim için düzelt. Bir eğim vardı. Sözde bir bileşik anahtar için iyi bir karakter gibi görünüyordu.
richard

Bu uzantı yöntemi, izin verilmeyen birkaç karakteri kaldırmıyor. Örneğin: boşluk, "(", ")" ... docs.microsoft.com/en-us/rest/api/storageservices/…
Tiago Andrade e Silva

6

Aynı sorunla karşılaştım ama benim durumumdaki sebep boyuttan kaynaklanıyordu. Ek istisna özelliklerini (RequestInformation.ExtendedErrorInformation) araştırdıktan sonra, nedeni buldu:

ErrorCode: PropertyValueTooLarge ErrorMessage: Özellik değeri izin verilen maksimum boyutu (64KB) aşıyor. Özellik değeri bir dizeyse UTF-16 olarak kodlanmıştır ve maksimum karakter sayısı 32K veya daha az olmalıdır.


5

benim durumumda bunu yapmaya çalışıyordum:

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

ContainerName nedeniyle SessionMaterials(Pascal Case ve Camel Case: D'de bir alışkanlık olarak yazma) 400 hatalı isteğe neden oluyordu. Yani, yapmalıyım sessionmaterials. ve işe yaradı.

Umarım bu birisine yardımcı olur.

Not: - Sadece istisna http yanıtını kontrol edin veya istek ve yanıtı yakalamak için fiddler'ı kullanın.


3

benim durumumda: Konteyner adı büyük harfti. karakterleri kullanırken sınırlamalar vardır. görüntü açıklamasını buraya girin


Bu, tablo özelliği adları için de geçerlidir.
Iain Ballard


1

Tüm Tablo Servis Hata Kodları hakkında MS'ten bir dokümantasyon burada bulunabilir


1

Aynı BadRequest (400) Hatası aldım, sonunda manuel olarak dolduruyorum:

görüntü açıklamasını buraya girin

Ve benim için çalıştı. Bu yardımcı olur umarım!


Bu cevap doğrudur. Yaklaşık bir saatini boşa harcadım ve Timestampmanuel olarak oluşturulması gerektiğini bile ayarlıyor . Gerçekten can sıkıcı.
Roman Koliada

0

Ben de aynı tür sorunlarla karşılaştım. Benim durumumda PartitionKey değeri ayarlanmadı, bu nedenle varsayılan olarak PartitionKey değeri null oldu, bu daObject reference not set to an instance of an object. istisnaya

PartitionKey veya RowKey için uygun değerleri sağlayıp sağlamadığınızı kontrol edin, böyle bir sorunla karşılaşabilirsiniz.


0

Davalarımı düzelttim ve iyi çalıştı

Vakalarım:

  1. Satır anahtarı doğru biçimde değil (400).
  2. Bölüm anahtarı ve satır anahtarının kombinasyonu benzersiz değil (409).

0

ZRS (Bölge Yedekli Depolama) kullandığım için 400 Hatalı İstek alıyordum ve Analytics bu tür depolama için kullanılamıyor. Analytics kullandığımın farkında değildim.

Saklama kabını sildim ve GRS olarak yeniden oluşturdum ve şimdi iyi çalışıyor.


0

Varlık bir DateTime özelliğine sahipken (= DateTime.MinValue) bir (400) Hatalı İstek, StatusMessage: Hatalı İstek, Hata Kodu: OutOfRangeInput alıyordum


0

Benim durumumda: Kısa çizgi içeren bir etiket adıyla blob meta verilerini dahil ettim.

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

Çizgi "added-by" problemdi ve daha sonra RTFM bana etiket adlarının C # tanımlayıcı kurallarına uyması gerektiğini söyledi.

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

Alt çizgi iyi çalışıyor.


0

Benim durumumda, varlık sınıfıma PartitionKey ve Rowkey eklememeliyim. Temel sınıftan olmalıdır. Aşağıda sadece çalışır.

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


      public TableRunLogMessage() { }
}

0

NodeJS kullanıyorsanız ve bu gönderiye rastladıysanız, yalnızca hata nesnenizde o güzel ayrıntılı bilgiyi almadığınızı bulmak için; bu ayrıntıları almak için bir proxy kullanabilirsiniz. Ancak, burada kimse bir proxy'nin NASIL kullanılacağından bahsetmediğinden.

NodeJS ile en basit yol, iki çevresel değişken ayarlamaktır:

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.

Aslında C # kullanıyorsanız, bu yazının yazarının yaptığı gibi; Fiddler'ı basitçe kurabilir ve kesişmesi için ayarlayabilirsiniz. Varsayılan olarak istekleri durdurması gerekir. Ayrıca Fiddler'in sertifikasına güvenmeniz veya Node'un "NODE_TLS_REJECT_UNAUTHORIZED = 0" eşdeğerini yapmanız gerekebilir.


0

Azure Storage Account Table API'den 400-BadRequest yanıtı aldım. İstisna bilgileri, "Erişilen hesabın http'yi desteklemediğini" gösterdi. Aşağıdaki resimde gösterildiği gibi depolama hesabı yapılandırmasında "Güvenli aktarım gerekli" etkinleştirildiğinde bağlantı dizesinde https kullanmamız gerektiğini düşündüm.görüntü açıklamasını buraya girin


0

Benim durumumda, "TableBotDataStore" sınıfının (MS bot çerçevesi) yeni bir örnek oluşturmak için "tableName" parametresini "master-bot" gibi kısa çizgi ile geçiriyoruz ve TableBotDataStore yalnızca harf ve rakamlarla tablo adlarına sahip olabilir


0

Aynı sorunu yaşadım, işlev containerNameKeydizeyi geçiyordu . hata veren kod aşağıdadır

container = blobClient.GetContainerReference(containerNameKey) 

Olarak değiştirdim

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

İşe yaradı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.