36
votes

I'm developing an ASP.Net MVC 4 app and I'm using Azure Blob to store the images that my users are going to upload. I have the following code:

 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
    } 

as soon as the if statement is excecuted I'm getting the following exception:

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

I thought it was the container's name but I don't see anything wrong with it. The connection string seems to create a good storage with all details for the blob. I'm at a loss. I've researched the web and everyone is saying it's a naming problem but I can't find anything wrong with it.

Test Container name that I used: imageads-57905553-8585-4d7c-8270-be9e611eda81

The Container has the following uri: {http://127.0.0.1:10000/devstoreaccount1/imageads-57905553-8585-4d7c-8270-be9e611eda81}

UPDATE: I have changed the container name to just image and I still get the same exception. also the development connection string is as follows: <add name="StorageConnection" connectionString="UseDevelopmentStorage=true" />

12

12 Answers

92
votes

As you found through your research, the problem is the name.

You say that your test container is named imageads-57905553-8585-4d7c-8270-be9e611eda81, but in your code you are using ImageAds-57905553-8585-4d7c-8270-be9e611eda81. Notice the difference in capitalization. If you switch your container name to all lower case it will work correctly.


For more information, see #3 under Container Names at Naming and Referencing Containers, Blobs, and Metadata:

3. All letters in a container name must be lowercase.
11
votes

To expand on @kwill's answer, I implemented a solution for converting any string into an acceptable container name, based on 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();
}

Then, when you try to get the container, clean it up first:

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

I actually ended up finding the problem.

My problem was that the blob storage emulator would not start (the other emulators would start and I missed the blob). The problem ended up being that the port 10000 (default blob emulator port) was already being used by another software. I used Netstat cmd tool to see which software it was, killed it and its now working like a charm!!! Thanks everyone!!

5
votes

Make sure your versions of the storage libraries and storage emulator aren't "out of sync". I updated my libraries but didn't update the emulator to the latest version and got this exact situation.

4
votes

If you have just updated the WindowsAzure.Storage nuget package and your app started crashing with http error 400 bad request :

In my case it happened when I updated to 8.2.1 and my local emulator was version 5.1.

My solution is this :

  1. Go to Microsoft Azure SDK page here.
  2. Search for "Azure Storage Emulator" and download the latest storage emulator. Usually at the middle of the page to the left in "Command-line tools" section
  3. Install the latest emulator
  4. You are good to go.

When I downloaded Storage Emulator 5.2 and upgraded from 5.1 the errors stopped. Such an error happened several times to me already.

My humble request if anybody from Microsoft Azure Storage Emulator team reads this - Please add a check for development mode and throw a meaningful exception with the message like - "You have Azure Storage Emulator version X.Y.Z installed. In order to use the current WindowsAzure.Storage library **V.V.V with Azure Emulator you need to install version Z.Z.Z of the emulator from this link".** or whatever you consider useful.

This kind of problem have wasted several hours of my time and I suppose the same happened to thousands of developers around the world and still this exception sits there - for more than 4 years!

3
votes

I just had this issue and fixed it.

My container name was fine, but I accidentally had the AccountName parameter in my connection string capitalized. This led to my 400.

3
votes

Mine was a stupid naming problem! Apparently we are not allowed to use uppercase in the names.

I've just changed this:

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

To

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

From experimentation it appears as though container names must always also be lower case. There must be an implicit conversion internally, which causes it to create the original blob in lower case, but not when it compares it in createifnotexists(async). But when it goes to re-create it, it lower cases it again, which results in a conflict. This is a best guess.

2
votes

I encountered this error after updating the packages but not my code. My issue is that the connection string format and content has changed since I first started using Azure Storage several years ago. Make sure to update your connection string appropriately from the access keys options within the azure portal.

In my case: I was missing this in my connection string: EndpointSuffix=core.windows.net

1
votes

I tried reproducing your issue, but it looks like you are using an older version of the client library, since container.CreateIfNotExist() is now container.CreateIfNotExists(). Have you considered upgrading the the latest client version (2.1)?

1
votes

it's necessary view the httpstatusmessage in exception: in my case the error was because The requested URI does not represent any resource on the server.

so i've seen that my BlobContainerName not contains the right container (or not exists)

CloudBlobContainer container = > blobClient.GetContainerReference(BlobContainerName);

other case i've seen is the wrong name of container. blobcontainername that must be a name like "mycontainer1" or "mycontainer2" and so on

here the code to add container

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

The simple solution to this problem is, container should always be in lower case. I had the same issue, which got resolved after changing container name to all in lower case.