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