Azure Blob 400 关于创建容器的错误请求

Posted

技术标签:

【中文标题】Azure Blob 400 关于创建容器的错误请求【英文标题】:Azure Blob 400 Bad request on Creation of container 【发布时间】:2013-11-05 03:51:25 【问题描述】:

我正在开发一个 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

更新: 我已将容器名称更改为 image,但仍然遇到相同的异常。开发连接字符串如下:<add name="StorageConnection" connectionString="UseDevelopmentStorage=true" />

【问题讨论】:

【参考方案1】:

正如您通过研究发现的那样,问题出在名称上。

您说您的测试容器名为imageads-57905553-8585-4d7c-8270-be9e611eda81,但在您的代码中您使用的是ImageAds-57905553-8585-4d7c-8270-be9e611eda81。注意大小写的不同。如果您将容器名称切换为全小写,它将正常工作。

有关更多信息,请参阅Naming and Referencing Containers, Blobs, and Metadata 的容器名称下的 #3:

3. 容器名称中的所有字母必须小写。

【讨论】:

您好,感谢您的回复。该语句的末尾有一个.ToLower(),它将整个字符串转换为小写。在任何一种情况下,我都想也许我错过了一些东西,然后我把名字改为静态image,我也遇到了同样的例外。 在我的情况下,我的容器名称太短(它必须至少 3 个字符长)【参考方案2】:

为了扩展@kwill 的答案,我实现了一个解决方案,用于将任何字符串转换为可接受的容器名称,基于Azure's rules for container naming:

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

【讨论】:

虽然这可行,但我通常会尽量避免这样的解决方案,因为您可能会遇到冲突(例如,两个不同的名称都解析为相同的名称)【参考方案3】:

我实际上最终找到了问题。

我的问题是 blob 存储模拟器无法启动(其他模拟器会启动,但我错过了 blob)。问题最终是端口 10000(默认 blob 模拟器端口)已被另一个软件使用。我使用Netstat cmd 工具查看它是哪个软件,杀死它,它现在像魅力一样工作!!!谢谢大家!!

【讨论】:

使用netstat help我找到并使用了netstat -b -n,它列出了我可以在任务管理器中关闭的项目。【参考方案4】:

确保您的存储库和存储模拟器版本没有“不同步”。我更新了我的库,但没有将模拟器更新到最新版本并得到了这种确切的情况。

【讨论】:

谢谢!通过 NuGet 升级 WindowsAzure.Storage 包并收到此错误。卸载并下载了最新版本的 Azure 存储模拟器,这清除了错误并让一切恢复正常。【参考方案5】:

如果您刚刚更新 WindowsAzure.Storage nuget 包并且您的应用开始崩溃并出现 http error 400 bad request

就我而言,它发生在我更新到 8.2.1 并且我的本地模拟器是 5.1 版时。

我的解决方案是这样的:

    转到 Microsoft Azure SDK 页面here. 搜索“Azure Storage Emulator”并下载最新的存储模拟器。通常在“命令行工具”部分左侧的页面中间 安装最新的模拟器 你可以走了。

当我下载 Storage Emulator 5.2 并从 5.1 升级时,错误停止了。 这样的错误我已经发生过好几次了。

My humble request if anybody from Microsoft Azure Storage Emulator team reads this - 请添加对开发模式的检查并抛出一个有意义的异常,如 - “您已安装 Azure Storage Emulator 版本 XYZ。为了使用当前的 WindowsAzure.Storage 库 **VVV 使用 Azure 模拟器,您需要从此链接安装模拟器的 ZZZ 版本。** 或您认为有用的任何东西。

这种问题浪费了我几个小时的时间,我想全世界成千上万的开发人员也遇到了同样的问题,但这个异常仍然存在 - 超过 4 年!

【讨论】:

【参考方案6】:

我刚刚遇到了这个问题并修复了它。

我的容器名称很好,但我不小心将连接字符串中的 AccountName 参数大写了。这导致了我的 400。

【讨论】:

【参考方案7】:

我的是一个愚蠢的命名问题!显然,我们不允许在名称中使用大写

我刚刚改变了这个:

CloudBlobContainer container = blobClient.GetContainerReference("MyContainer");
container.CreateIfNotExists();

收件人

CloudBlobContainer container = blobClient.GetContainerReference("mycontainer");
container.CreateIfNotExists();

【讨论】:

【参考方案8】:

从实验看来,容器名称似乎也必须始终小写。内部必须有一个隐式转换,这会导致它以小写形式创建原始 blob,但在 createifnotexists(async) 中比较它时不会。但是当它重新创建它时,它会再次降低它的大小写,这会导致冲突。这是一个最好的猜测。

【讨论】:

【参考方案9】:

我在更新软件包后遇到了这个错误,但不是我的代码。我的问题是,自从几年前我第一次开始使用 Azure 存储以来,连接字符串的格式和内容发生了变化。确保从 azure 门户中的访问密钥选项适当地更新您的连接字符串。

在我的情况下:我的连接字符串中缺少这个: EndpointSuffix=core.windows.net

【讨论】:

【参考方案10】:

我尝试重现您的问题,但您似乎使用的是旧版本的客户端库,因为 container.CreateIfNotExist() 现在是 container.CreateIfNotExists()。您是否考虑过升级最新的客户端版本 (2.1)?

【讨论】:

嗨,其实我只是发现了问题,这不是问题。但是我没有意识到有一个更新的(实际上是更新的)包可用并且已经升级了它。 我的问题是模拟器过时了 - 安装最新的模拟器(我不需要移动到整个 2.7 SDK)解决了机器上的问题。 【参考方案11】:

有必要在异常中查看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 "";
        

【讨论】:

【参考方案12】:

解决这个问题的简单方法是,容器应该总是小写。我遇到了同样的问题,将容器名称更改为全部小写后得到解决。

【讨论】:

以上是关于Azure Blob 400 关于创建容器的错误请求的主要内容,如果未能解决你的问题,请参考以下文章

Azure:无法从 Azure 函数 HttpTrigger 读取 Blob 文本(400 - 错误请求错误)

Azure 使用 REST api 和托管标识创建 blob 容器 - 403 错误

创建 Azure 存储 Blob 容器时出现错误 403(已启用存储防火墙

如何删除 Azure Blob 容器中的文件夹

通过 C# Azure 函数生成 Blob 容器

Azure:使用容器创建存储帐户并在 Python 中将 blob 上传到其中