无法上传到azure Blob存储:远程服务器返回错误:(400)错误请求

时间:2014-06-28 19:34:08

标签: c# azure azure-storage azure-storage-blobs

我正在尝试创建一个实用程序,用于从Internet下载文件并将其再次上载到Azure blob存储。 Blob容器已经很好了;但由于某种原因,当我试图将文件上传到存储时,我收到“Bad Request 400”异常...容器名称已创建,小写字母,所以特殊字符。但我仍然不知道为什么我会得到例外!

请帮忙。

注意

  • 我没有使用任何模拟器......直接在云端测试。
  • 我的所有容器都有“公共容器”访问权限。

以下是例外:

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.

以下是代码:

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

编辑:存储异常

  

Microsoft.WindowsAzure.Storage.StorageException:远程服务器返回错误:(400)错误请求。 ---&GT; System.Net.WebException:远程服务器返回错误:(400)错误请求。      在System.Net.HttpWebRequest.GetRequestStream(TransportContext&amp; context)      在System.Net.HttpWebRequest.GetRequestStream()      在Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync [T](RESTCommand 1 cmd, IRetryPolicy policy, OperationContext operationContext) --- End of inner exception stack trace --- at Microsoft.WindowsAzure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand 1 cmd,IRetryPolicy策略,OperationContext operationContext)      在Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStreamHelper(Stream source,Nullable`1 length,AccessCondition accessCondition,BlobRequestOptions options,OperationContext operationContext)      在Microsoft.WindowsAzure.Storage.Blob.CloudBlockBlob.UploadFromStream(Stream source,AccessCondition accessCondition,BlobRequestOptions options,OperationContext operationContext)      在TelawatAzureUtility.StorageService。&lt;&gt; c__DisplayClass4.b__12(任务任务)\ psf \ Home \ Documents \ Visual Studio 14 \ Projects \ Telawat Azure Utility \ TelawatAzureUtility \ StorageService.cs:第128行   请求信息   请求ID:   RequestDate:星期六,2014年6月28日20:12:14 GMT   StatusMessage:错误请求

编辑2:请求信息:

enter image description here

enter image description here

编辑3:问题来自WebUtils ..我用下面的代码替换它,它的工作原理!我将添加weUtils代码,也许你可以帮助知道它有什么问题。

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

WebUtils代码:

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

当我尝试这段代码时......“等待”永远不会完成或完成!

webUtil.DownloadAsync(url, downloadedFilePath).Wait()

6 个答案:

答案 0 :(得分:31)

您是否尝试过在azure门户上手动创建容器?它对您可以为容器提供的名称有一些限制。

例如:容器名称不能包含大写字母。

如果您请求名称无效的容器,则会导致您收到的(400)错误请求。所以检查你的&#34; containerName&#34;字符串。

答案 1 :(得分:17)

我遇到了同样的问题。我通过在存储配置中更改 TLS 版本来解决它;新的 TLS 版本 (1.2) 与旧版本的存储客户端不兼容。我将其更改为 1.0 并且可以正常工作。

存储的配置在 Azure 的门户中。

存储 -> 配置 -> TLS 版本:

storage configuration in portal

答案 2 :(得分:2)

我还在Azure存储消息队列中遇到此错误。

Azure存储消息队列名称也必须全部小写。 即:&#34; newqueueitem&#34;以小写字母命名。

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

// Create the queue if it doesn't already exist.
queue.CreateIfNotExists();

答案 3 :(得分:1)

我遇到了一个非常不同的错误请求消息。在这里张贴给可能会遇到同样的人。就我而言,我只是在其他资源组中移动资源。在那次改组中,天蓝色的一个小虫让我把我的存储空间指向了我所在地区没有的位置(&#34;东南亚和#34;)。因此,针对存储帐户的所有请求都返回了错误的请求消息。我花了一段时间才弄明白,因为我创建了另一个存储帐户进行测试,在创建时,azure不允许我选择&#34;东南亚&#34;作为一个选择的位置,所以我选择了另一个位置(&#34;东亚&#34;)然后一切正常。

答案 4 :(得分:1)

如果使用无效名称创建容器,将导致(400)错误请求。创建容器名称的约定如下:

  
      
  1. 容器名称必须以字母或数字开头,并且只能包含字母,数字和破折号(-)。
  2.   
  3. 每个破折号(-)必须紧跟在字母和数字之后;不允许连续的破折号   容器名称。
  4.   
  5. 容器名称中的所有字母都必须小写。
  6.   
  7. 容器名称的长度必须在3到63个字符之间。
  8.   

来源:https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata

答案 5 :(得分:0)

我在Azure中使用来自C#代码的一个UpperCase Letter创建队列时遇到了相同的问题。错误与队列名称有关。所有字符均应小写。将所有字符更改为小写字母后,它起作用了! :)

//Retrieve a reference to a queue
CloudQueue queue = queueClient.GetQueueReference("myqueue");
//Create a queue if it alredy doen't exists
queue.CreateIfNotExists();