使用 C# 中的 PUT 请求将内容写入 Azure 存储上的文件

Write content to a file on azure storage with using PUT request in C#

我正在尝试向 Azure 存储文件发出放置请求,我想在其中添加一些简单的内容。我更改了 URL 并在 url 的末尾添加了 ?comp=range 但我收到 403 错误响应。我在 .net 中创建了一个基本的控制台应用程序。

我的页眉是:

 const string requestMethod = "PUT";
            string urlPath = strShareName + "/" + "rahila.csv?comp=range";//+ "?comp=range  HTTP/1.1";
            String canonicalizedResource = String.Format("/{0}/{1}/{2}", StorageAccountName, strShareName, strFileName);
            try
            {
                //GetWebRequest(requestMethod, urlPath, canonicalizedResource, "CreateFile");
                HttpWebRequest request = null;
                try
                {
                    const string type = "file";
                    string MethodType = "CreateFile";
                    const string msVersion = "2015-04-05";
                    String dateInRfc1123Format = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
                    String canonicalizedHeaders = "";
                    string data = "rahila sted";
                    canonicalizedHeaders = String.Format("x-ms-date:{0}\nx-ms-version:{1}", dateInRfc1123Format, msVersion);
                    if (MethodType == "CreateFile")
                    {
                        canonicalizedHeaders = String.Format("x-ms-content-length:65536\nx-ms-date:{0}\nx-ms-type:file\nx-ms-version:{1}", dateInRfc1123Format, msVersion);
                    }

                    String stringToSign = "";


                    stringToSign = String.Format("{0}\n\n\n\n\n\n\n\n\n\n\n\n{1}\n{2}", requestMethod, canonicalizedHeaders, canonicalizedResource);

                    if (String.IsNullOrEmpty(stringToSign))
                    {
                        throw new ArgumentNullException("canonicalizedString");
                    }

                    String signature;

                    if (String.IsNullOrEmpty(stringToSign))
                    {
                        throw new ArgumentNullException("unsignedString");
                    }

                    if (Convert.FromBase64String(StorageKey) == null)
                    {
                        throw new ArgumentNullException("key");
                    }

                    Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(stringToSign);
                    using (HMACSHA256 hmacSha256 = new HMACSHA256(Convert.FromBase64String(StorageKey)))
                    {
                        signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
                    }


                    String authorizationHeader = String.Format(CultureInfo.InvariantCulture, "{0} {1}:{2}",
                                                               StorageScheme,
                                                               StorageAccountName, signature);
Uri uri = new Uri(FileEndPoint + urlPath);
request = (HttpWebRequest)WebRequest.Create(uri);
if (requestMethod != "Get")
{
    request.ContentLength = data.Length;
}
// string data = "Hello testing";
//int a= ((data.Length) + 1);

request.Method = "PUT";//requestMethod;
request.Headers.Add("x-ms-write", "update");
request.Headers.Add("x-ms-date", dateInRfc1123Format);
request.Headers.Add("x-ms-version", msVersion);
request.Headers.Add("x-ms-range", "bytes=0-65535"); // + ((data.Length) - 1));
request.Headers.Add("Authorization", authorizationHeader);

我得到异常的行是粗体格式。

HttpWebResponse response = null;
response = (HttpWebResponse)request.GetResponse();
string returnString = response.StatusCode.ToString();

任何人都可以帮我解决这个问题,或者指导我如何在不使用 azure 客户端的情况下将内容写入 azure 存储上的简单文件 API。

12 月 19 日更新:

使用Put Range上传内容到azure文件时,可以按照下面的代码(我假设你已经在azure文件共享上创建了一个文件,它的内容长度是大于正在上传的内容):

        static void UploadText()
        {
            string Account = "xxxx";
            string Key = "xxxx";
            string FileShare = "test1";
            string FileName = "11.txt";
            string apiversion = "2019-02-02";

            //the string to be uploaded to azure file, note that the length of the uploaded string should less than the azure file length
            string upload_text = "bbbbbbbbbbbbbbbbbbbbbbbb.";
            Console.WriteLine("the string length: " + upload_text.Length);
            DateTime dt = DateTime.UtcNow;
            string StringToSign = String.Format("PUT\n"
                + "\n" // content encoding
                + "\n" // content language
                + upload_text.Length + "\n" // content length
                + "\n" // content md5
                + "\n" // content type
                + "\n" // date
                + "\n" // if modified since
                + "\n" // if match
                + "\n" // if none match
                + "\n" // if unmodified since
                + "\n"//+ "bytes=0-" + (upload_text.Length - 1) + "\n" // range
                +"x-ms-date:" + dt.ToString("R") + "\nx-ms-range:bytes=0-"+(upload_text.Length-1) + "\nx-ms-version:" + apiversion + "\nx-ms-write:update\n" // headers
                + "/{0}/{1}/{2}\ncomp:range", Account, FileShare, FileName);

            string auth = SignThis(StringToSign, Key, Account);
            string method = "PUT";
            string urlPath = string.Format("https://{0}.file.core.windows.net/{1}/{2}?comp=range", Account, FileShare,FileName);
            Uri uri = new Uri(urlPath);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
            request.Method = method;
            request.ContentLength = upload_text.Length;

            request.Headers.Add("x-ms-range", "bytes=0-"+(upload_text.Length-1));
            request.Headers.Add("x-ms-write", "update");
            request.Headers.Add("x-ms-date", dt.ToString("R"));
            request.Headers.Add("x-ms-version", apiversion);
            request.Headers.Add("Authorization", auth);
            //request.Headers.Add("Content-Length", upload_text.Length.ToString());

            var bytes = System.Text.Encoding.ASCII.GetBytes(upload_text);

            using (var requestStream = request.GetRequestStream())
            {
                requestStream.Write(bytes, 0, bytes.Length);
            }


            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                //read the content
                Console.WriteLine("the response is:" + response.StatusCode);
            }
        }



        private static String SignThis(String StringToSign, string Key, string Account)
        {
            String signature = string.Empty;
            byte[] unicodeKey = Convert.FromBase64String(Key);
            using (HMACSHA256 hmacSha256 = new HMACSHA256(unicodeKey))
            {
                Byte[] dataToHmac = System.Text.Encoding.UTF8.GetBytes(StringToSign);
                signature = Convert.ToBase64String(hmacSha256.ComputeHash(dataToHmac));
            }

            String authorizationHeader = String.Format(
                  CultureInfo.InvariantCulture,
                  "{0} {1}:{2}",
                  "SharedKey",
                  Account,
                  signature);

            return authorizationHeader;
        }

然后在Main()方法中,可以调用UploadText()方法,我这边行得通


旧:

guide me how to write content to a simple file on azure storage without using the azure client API.

为此,您可以直接使用 Azure 文件存储 SDK Microsoft.Azure.Storage.File, version 11.1.1。而且我们总是建议使用 SDK 而不是使用 rest api,因为 SDK 易于使用。

这里是使用这个SDK的例子。

首先,在visual studio中创建一个.NET framework的控制台项目。然后安装这个 nuget 包 Microsoft.Azure.Storage.File, version 11.1.1.

代码:

using Microsoft.Azure.Storage;
using Microsoft.Azure.Storage.Auth;
using Microsoft.Azure.Storage.File;
using System;

namespace AzureFileTest2
{
    class Program
    {
        static void Main(string[] args)
        {
            string accountName = "xxx";
            string accountKey = "xxx";
            CloudStorageAccount storageAccount = new CloudStorageAccount(new StorageCredentials(accountName, accountKey), true);

            CloudFileClient cloudFileClient = storageAccount.CreateCloudFileClient();

            //make sure the file share named test1 exists.
            CloudFileShare fileShare = cloudFileClient.GetShareReference("test1");
            CloudFileDirectory fileDirectory = fileShare.GetRootDirectoryReference();
            CloudFile myfile = fileDirectory.GetFileReference("test123.txt");

            if (!myfile.Exists())
            {
                //if the file does not exists, then create the file and set the file max size to 100kb.
                myfile.Create(100 * 1024 * 1024);                
            }

            //upload text to the file
            //Besides using UploadText() method to directly upload text, you can also use UploadFromFile() / UploadFromByteArray() / UploadFromStream() methods as per your need.
            myfile.UploadText("hello, it is using azure storage SDK");

            Console.WriteLine("**completed**");
            Console.ReadLine();
        }
    }
}