Azure Blob 400 Плохой запрос о создании контейнера

Я разрабатываю приложение ASP.Net MVC 4, и я использую Azure Blob для хранения изображений, которые мои пользователи будут загружать. У меня есть следующий код:

 var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnection"].ConnectionString);

 var blobStorage = storageAccount.CreateCloudBlobClient();
 //merchantKey is just a GUID that is asociated with the merchant
 var containerName = ("ImageAds-" + merchant.merchantKey.ToString()).ToLower();
 CloudBlobContainer container = blobStorage.GetContainerReference(containerName);
 if (container.CreateIfNotExist())
    {
       //Upload the file
    } 

как только оператор if будет исключен, я получаю следующее исключение:

  {"The remote server returned an error: (400) Bad Request."}

Я думал, что это имя контейнера, но я не вижу в этом ничего плохого. Строка подключения, похоже, создает хорошее хранилище со всеми деталями для blob. Я в недоумении. Я исследовал Интернет, и все говорят, что это проблема с именами, но я не могу найти в этом ничего плохого.

Имя тестового контейнера, которое я использовал: imageads-57905553-8585-4d7c-8270-be9e611eda81

Контейнер имеет следующий uri: {http://127.0.0.1:10000/devstoreaccount1/imageads-57905553-8585-4d7c-8270-be9e611eda81}

UPDATE: Я изменил имя контейнера только на image, и я все равно получаю то же исключение. также строка соединения разработки следующая: <add name="StorageConnection" connectionString="UseDevelopmentStorage=true" />

Ответ 1

На самом деле я нашел проблему.

Моя проблема заключалась в том, что эмулятор памяти blob не запускался (другие эмуляторы запускались, и я пропустил blob). Проблема заключалась в том, что порт 10000 (порт эмулятора blob по умолчанию) уже использовался другим программным обеспечением. Я использовал инструмент Netstat cmd, чтобы узнать, какое программное обеспечение оно было, убило его и теперь оно работает как шарм!!! Спасибо всем!

Ответ 2

Как вы нашли в своем исследовании, проблема заключается в имени.

Вы говорите, что ваш тестовый контейнер имеет имя imageads-57905553-8585-4d7c-8270-be9e611eda81, но в вашем коде вы используете imageads-57905553-8585-4d7c-8270-be9e611eda81. Обратите внимание на разницу в капитализации. Если вы переключите имя контейнера на все строчные буквы, он будет работать правильно.


Для получения дополнительной информации см. № 3 под именами контейнеров в Именование и ссылки на контейнеры, Blobs и метаданные:

3. Все буквы в имени контейнера должны быть строчными.

Ответ 3

Чтобы расширить ответ на @kwill, я применил решение для преобразования любой строки в приемлемое имя контейнера на основе правил Azure для именования контейнеров:

public static string ToURLSlug(this string s)
{
    return Regex.Replace(s, @"[^a-z0-9]+", "-", RegexOptions.IgnoreCase)
        .Trim(new char[] { '-' })
        .ToLower();
}

Затем, когда вы пытаетесь получить контейнер, сначала очистите его:

CloudBlobContainer container = blobClient.GetContainerReference(bucket.ToURLSlug());

Ответ 4

Убедитесь, что ваши версии библиотек хранения и эмулятора хранилища не "не синхронизированы". Я обновил свои библиотеки, но не обновил эмулятор до последней версии и получил эту точную ситуацию.

Ответ 5

Если у вас есть только что обновленный пакет nixet WindowsAzure.Storage, и ваше приложение начало сбой с ошибкой 400 ошибок 400:

>

В моем случае это произошло, когда я обновился до 8.2.1, а мой локальный эмулятор был версии 5.1.

Мое решение таково:

  • Перейдите на страницу Microsoft Azure SDK здесь.
  • Найдите "Azure Storage Emulator" и загрузите последний эмулятор хранилища. Обычно в середине страницы слева в разделе "Инструменты командной строки"
  • Установите последний эмулятор
  • Вам хорошо идти.

Когда я загрузил Storage Emulator 5.2 и обновился с 5.1, ошибки были остановлены. Такая ошибка повторялась уже несколько раз.

Мой скромный запрос, если кто-нибудь из команды Microsoft Azure Storage Emulator читает это - Пожалуйста, добавьте проверку для режима разработки и бросьте осмысленное исключение с помощью сообщение типа - "У вас установлена ​​версия Azure Storage Emulator XYZ. Чтобы использовать текущую библиотеку WindowsAzure.Storage ** VVV с Azure Emulator, вам нужно установить версию ZZZ эмулятора по этой ссылке". ** или все, что вы считаете полезным.

Эта проблема потеряла несколько часов моего времени, и я полагаю, что то же самое произошло с тысячами разработчиков по всему миру, и все же это исключение сидит там - уже более 4 лет!

Ответ 6

Из экспериментов кажется, что имена контейнеров также должны быть в нижнем регистре. Должно существовать неявное преобразование внутри, что заставляет его создавать исходный blob в нижнем регистре, но не тогда, когда он сравнивает его в createifnotexists (async). Но когда он собирается воссоздать его, он снова уменьшает число случаев, что приводит к конфликту. Это лучшее предположение.

Ответ 7

У меня была эта проблема и исправлена.

Мое имя контейнера было прекрасным, но у меня случайно был параметр AccountName в моей строке соединения с заглавной буквы. Это привело к моим 400.

Ответ 8

Я попытался воспроизвести вашу проблему, но похоже, что вы используете более старую версию клиентской библиотеки, так как container.CreateIfNotExist() теперь container.CreateIfNotExists(). Рассматривали ли вы обновление последней версии клиента (2.1)?

Ответ 9

необходимо просмотреть httpstatusmessage в исключении: в моем случае ошибка была в том, что Запрошенный URI не представляет никакого ресурса на сервере.

поэтому я видел, что мой BlobContainerName не содержит правильный контейнер (или не существует)

CloudBlobContainer container = > blobClient.GetContainerReference(BlobContainerName);

В другом случае я видел неправильное имя контейнера. blobcontainername, которое должно быть именем типа mycontainer1 или mycontainer2 и т.д.

здесь код для добавления контейнера

try
        {
            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);

            // Create the blob client.
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();

            // Retrieve reference to a previously created container.
            CloudBlobContainer container = blobClient.GetContainerReference(BlobContainerName);

            container.CreateIfNotExists();

           //creo se non esiste e aggiungo i permessi
            BlobContainerPermissions containerPermissions = new BlobContainerPermissions();
            containerPermissions.PublicAccess = BlobContainerPublicAccessType.Blob;
            container.SetPermissions(containerPermissions);

            // Retrieve reference to a blob named "myblob".
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(Filename); 

            blockBlob.UploadFromStream(inFileUpload);
        }
        catch (Exception ex)
        {
            return "";
        }