Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot upload to azure Blob Storage: The remote server returned an error: (400) Bad Request

I'm trying to create a utility to download file from the internet and upload it again to Azure blob storage. Blob containers already created well; But for some reason i'm getting "Bad Request 400" exception when i tried to upload the file to storage ... Container name is created, small letters, so special characters. But I still do not know why i'm getting the exception!

Please help.

Note:

  • I'm not using any emulator ... Directly testing on the cloud.
  • All of my containers with "Public Container" access option.

Here is the exception:

An exception of type 'Microsoft.WindowsAzure.Storage.StorageException' 
occurred in Microsoft.WindowsAzure.Storage.dll but was not handled in user code
Additional information: The remote server returned an error: (400) Bad Request.

And here is the code:

foreach (var obj in objectsList)
{
     var containerName = obj.id.Replace("\"", "").Replace("_", "").Trim();
     CloudBlobContainer blobContainer = blobClient.GetContainerReference(containerName);

     if (blobContainer.Exists())
     {
         var fileNamesArr = obj.fileNames.Split(new char[] { '#' }, StringSplitOptions.RemoveEmptyEntries);

         foreach (var sora in fileNamesArr)
         {
             int soraInt = int.Parse(sora.Replace("\"", ""));
             String fileName = String.Format("{0}.mp3", soraInt.ToString("000"));

             var url = String.Format("http://{0}/{1}/{2}", obj.hostName.Replace("\"", ""), obj.id.Replace("\"", ""), fileName.Replace("\"", "")).ToLower();

             var tempFileName = "temp.mp3";

             var downloadedFilePath = Path.Combine(Path.GetTempPath(), tempFileName).ToLower();

             var webUtil = new WebUtils(url);
             await webUtil.DownloadAsync(url, downloadedFilePath).ContinueWith(task =>
             {
                 var blobRef = blobContainer.GetBlockBlobReference(fileName.ToLower());
                 blobRef.Properties.ContentType = GetMimeType(downloadedFilePath);

                 using (var fs = new FileStream(downloadedFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                 {
                     blobRef.UploadFromStream(fs); // <--- Exception
                 }
             });
         }
      }
      else
      {
          throw new Exception(obj.id.Replace("\"", "") + " Container not exist!");
      }
}

Edit: The Storage Exception

Microsoft.WindowsAzure.Storage.StorageException: The remote server returned an error: (400) Bad Request. ---> System.Net.WebException: The remote server returned an error: (400) Bad Request. at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context) at System.Net.HttpWebRequest.GetRequestStream() at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext) --- End of inner exception stack trace --- at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand1 cmd, IRetryPolicy policy, OperationContext operationContext) at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamHelper(Stream source, Nullable`1 length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) at Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStream(Stream source, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext) at TelawatAzureUtility.StorageService.<>c__DisplayClass4.b__12(Task task) in \psf\Home\Documents\Visual Studio 14\Projects\Telawat Azure Utility\TelawatAzureUtility\StorageService.cs:line 128 Request Information RequestID: RequestDate:Sat, 28 Jun 2014 20:12:14 GMT StatusMessage:Bad Request

Edit 2: Request Information:

enter image description here

enter image description here

Edit 3: The problem comes from WebUtils .. I replaced it with below code and it works! I will add weUtils code, maybe you can help to know what is the problem with it.

HttpClient client = new HttpClient();
var stream = await client.GetStreamAsync(url);

WebUtils Code:

public class WebUtils
{
    private Lazy<IWebProxy> proxy;

    public WebUtils(String url)
    {
        proxy = new Lazy<IWebProxy>(() => string.IsNullOrEmpty(url) ? null : new WebProxy {
            Address = new Uri(url), UseDefaultCredentials = true });
    }

    public IWebProxy Proxy
    {
        get { return proxy.Value; }
    }

    public Task DownloadAsync(string requestUri, string filename)
    {
        if (requestUri == null)
            throw new ArgumentNullException("requestUri is missing!");

        return DownloadAsync(new Uri(requestUri), filename);
    }

    public async Task DownloadAsync(Uri requestUri, string filename)
    {
        if (filename == null)
            throw new ArgumentNullException("filename is missing!");

        if (Proxy != null)
        {
            WebRequest.DefaultWebProxy = Proxy;
        }

        using (var httpClient = new HttpClient())
        {
            using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
            {
                using (Stream contentStream = await (await httpClient.SendAsync(request)).Content.ReadAsStreamAsync())
                {
                    using (var stream = new FileStream(filename, FileMode.Create, FileAccess.Write))
                    {
                        contentStream.CopyTo(stream);
                        stream.Flush();
                        stream.Close();
                    }
                    contentStream.Close();
                }
            }
        }
    }
}

Also when I tried this code ... the 'Wait' will never finish or completed!

webUtil.DownloadAsync(url, downloadedFilePath).Wait()
like image 839
bunjeeb Avatar asked Jun 28 '14 19:06

bunjeeb


4 Answers

Have you tried creating a container manually on azure portal? It has some limitations on what name you can give containers.

For example: Container name cannot contain upper case letters.

If you request a container with an invalid name, it will result in (400) Bad Request, which you are getting. So check your "containerName" string.

like image 199
siddhant Avatar answered Oct 07 '22 03:10

siddhant


I had the same problem. I resolved it by changing the TLS version in the configuration of the storage; the new TLS version (1.2) is not compatible with the older version of the storage client. I changed it to the 1.0 and it works.

The configuration of the storage is in the portal of Azure.

Storage -> Configuration -> TLS Version:

storage configuration in portal

like image 23
Oscar Ernesto Loyola Sánchez Avatar answered Oct 07 '22 05:10

Oscar Ernesto Loyola Sánchez


I also got this error with the Azure Storage Message Queues.

The Azure Storage Message Queue names must also be all lowercase. ie: "newqueueitem" name in lowercase.

// Retrieve a reference to a queue.
CloudQueue queue = queueClient.GetQueueReference("newqueueitem");

// Create the queue if it doesn't already exist.
queue.CreateIfNotExists();
like image 3
Alex Avatar answered Oct 07 '22 03:10

Alex


If you create a container with an invalid name, it will result in (400) Bad Request. There are some convention for creating container name as below:

  1. Container names must start with a letter or number, and can contain only letters, numbers, and the dash (-) character.
  2. Every dash (-) character must be immediately preceded and followed by a letter or number; consecutive dashes are not permitted in container names.
  3. All letters in a container name must be lowercase.
  4. Container names must be from 3 through 63 characters long.

Source: https://learn.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata

like image 2
Khabir Avatar answered Oct 07 '22 04:10

Khabir