C# 来自C的Azure BLOB存储REST调用#

C# 来自C的Azure BLOB存储REST调用#,c#,azure,azure-storage,C#,Azure,Azure Storage,我正试图通过控制台应用程序与Azure Blob存储上的容器通信。我不能使用SDK,因此REST是我唯一的选择。语言是C#和.NET4.5.2 我尝试了这两个代码,都返回了相同的错误 我收到的错误是400个错误请求 是否有其他人也面临同样的问题并成功地解决了它 我为几乎所有内容添加了带有(*)的CORS规则 代码是两个链接的精确副本,因此我不在这里添加它 class Program { static void Main(string[] args) {

我正试图通过控制台应用程序与Azure Blob存储上的容器通信。我不能使用SDK,因此REST是我唯一的选择。语言是C#和.NET4.5.2

我尝试了这两个代码,都返回了相同的错误

我收到的错误是400个错误请求

是否有其他人也面临同样的问题并成功地解决了它

我为几乎所有内容添加了带有(*)的CORS规则

代码是两个链接的精确副本,因此我不在这里添加它

    class Program
   {
    static void Main(string[] args)
    {

        UploadBlobWithRestAPI();
    }

    public static void UploadBlobWithRestAPI()
    {

        string storageKey = "ffFJwPXTqyYvRoubNQEti/aQUUMwn41BG3KDtl/yGpG4DR1eKaHRq6Bhbw==";
        string storageAccount = "xyz";
        string containerName = "notes";
        string blobName = "test567";

        string method = "PUT";
        string sampleContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla id euismod urna. Maecenas scelerisque dolor purus, sed ullamcorper ipsum lobortis non. Nulla est justo, sodales at venenatis a, faucibus";
        int contentLength = Encoding.UTF8.GetByteCount(sampleContent);

        string requestUri = $"https://xyz.blob.core.windows.net/notes/test567";

        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);

        string now = DateTime.UtcNow.ToString("R");

        request.Method = method;
        request.ContentType = "text/plain; charset=UTF-8";
        request.ContentLength = contentLength;

        request.Headers.Add("x-ms-version", "2018-01-11");
        request.Headers.Add("x-ms-date", now);
        request.Headers.Add("x-ms-blob-type", "BlockBlob");
        request.Headers.Add("Authorization", AuthorizationHeader2(method, now, request, storageAccount, storageKey, containerName, blobName));

        using (Stream requestStream = request.GetRequestStream())
        {
            requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
        }

        using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
        {
            Console.WriteLine(resp.StatusCode.ToString());
            Console.ReadKey();
        }

    }

    public static string AuthorizationHeader2(string method, string now, HttpWebRequest request, string storageAccount, 
        string storageKey, string containerName, string blobName)
    {

        string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:"+ DateTime.UtcNow.ToString("R") +"\nx-ms-version:2018-01-11";
        string urlResource = "/xyz/notes/test567";
        string stringToSign =  method + "\n\n\n" + request.ContentLength + 
            "\n\n" + request.ContentType +"\n\n\n\n\n\n\n" + headerResource + "\n" + urlResource;


        HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
        string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));

        String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
        return AuthorizationHeader;
    }


}

您的代码有两个问题:

  • 您使用的服务版本无效。最新的存储服务REST API版本是
    2017-04-17
    ,而不是
    2018-01-11
    。一旦你改变了,你不会得到400错误(但你会得到403错误)
  • headerResource
    中,您正在生成一个新的日期/时间值,该值将不同于
    x-ms-date
    标题中的日期/时间值。因此,您将得到403错误。因此,基本上您的代码是:

        string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:" + now + "\nx-ms-version:2017-04-17";
    
  • 我做了这两个修复,之后我就可以上传数据了

    以下是完整的代码:

        public static void UploadBlobWithRestAPI()
        {
    
            string storageKey = "ffFJwPXTqyYvRoubNQEti/aQUUMwn41BG3KDtl/yGpG4DR1eKaHRq6Bhbw==";
            string storageAccount = "xyz";
            string containerName = "notes";
            string blobName = "test567";
    
            string method = "PUT";
            string sampleContent = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla id euismod urna. Maecenas scelerisque dolor purus, sed ullamcorper ipsum lobortis non. Nulla est justo, sodales at venenatis a, faucibus";
            int contentLength = Encoding.UTF8.GetByteCount(sampleContent);
    
            string requestUri = $"https://xyz.blob.core.windows.net/notes/test567";
    
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
    
            string now = DateTime.UtcNow.ToString("R");
    
            request.Method = method;
            request.ContentType = "text/plain; charset=UTF-8";
            request.ContentLength = contentLength;
    
            request.Headers.Add("x-ms-version", "2017-04-17");
            request.Headers.Add("x-ms-date", now);
            request.Headers.Add("x-ms-blob-type", "BlockBlob");
            request.Headers.Add("Authorization", AuthorizationHeader2(method, now, request, storageAccount, storageKey, containerName, blobName));
    
            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(Encoding.UTF8.GetBytes(sampleContent), 0, contentLength);
            }
    
            using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
            {
                Console.WriteLine(resp.StatusCode.ToString());
                Console.ReadKey();
            }
    
        }
    
        public static string AuthorizationHeader2(string method, string now, HttpWebRequest request, string storageAccount,
            string storageKey, string containerName, string blobName)
        {
    
            string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:" + now + "\nx-ms-version:2017-04-17";
            string urlResource = "/xyz/notes/test567";
            string stringToSign = method + "\n\n\n" + request.ContentLength +
                "\n\n" + request.ContentType + "\n\n\n\n\n\n\n" + headerResource + "\n" + urlResource;
    
    
            HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(storageKey));
            string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
    
            String AuthorizationHeader = String.Format("{0} {1}:{2}", "SharedKey", storageAccount, signature);
            return AuthorizationHeader;
        }
    

    有错误代码吗?()阅读并显示相关代码。是否可以编辑您的问题并包含代码。否,因为在使用(HttpWebResponse resp=(HttpWebResponse)request.GetResponse()初始化响应对象之前,它会引发异常。请添加
    request.Headers.add(“x-ms-blob-type”,“BlockBlob”)
    并查看这是否解决了问题。您的请求中缺少此必需的标头。