来自C#的Azure BLOB存储REST调用 [英] Azure BLOB storage REST call from C#
问题描述
我正在尝试通过控制台应用程序与Azure Blob存储上的容器通信.我无法使用SDK,因此REST是我唯一的选择.使用.NET 4.5.2.的语言是C#.
我尝试了这两个代码,并且都返回相同的错误
还有其他人遇到过同样的问题并成功解决了吗?
我为几乎所有内容添加了带有(*)的CORS规则
该代码与两个链接完全相同,因此我不在这里添加它.
类Program{静态void Main(string [] args){UploadBlobWithRestAPI();}公共静态无效UploadBlobWithRestAPI(){字符串storageKey ="ffFJwPXTqyYvRoubNQEti/aQUUMwn41BG3KDtl/yGpG4DR1eKaHRq6Bhbw ==";字符串storageAccount ="xyz";字符串containerName ="notes";字符串blobName ="test567";字符串方法="PUT";string sampleContent ="Lorem ipsum dolor sit amet,consectetur adipiscing elit.Nulla id euismod urna.int contentLength = Encoding.UTF8.GetByteCount(sampleContent);字符串requestUri = $"https://xyz.blob.core.windows.net/notes/test567";HttpWebRequest request =(HttpWebRequest)WebRequest.Create(requestUri);现在的字符串= 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",现在);request.Headers.Add("x-ms-blob-type","BlockBlob");request.Headers.Add("Authorization",AuthorizationHeader2(method,now,request,storageAccount,storageKey,containerName,blobName));使用(流requestStream = request.GetRequestStream()){requestStream.Write(Encoding.UTF8.GetBytes(sampleContent),0,contentLength);}使用(HttpWebResponse resp =(HttpWebResponse)request.GetResponse()){Console.WriteLine(resp.StatusCode.ToString());Console.ReadKey();}}公共静态字符串AuthorizationHeader2(字符串方法,现在的字符串,HttpWebRequest请求,字符串storageAccount,字符串storageKey,字符串containerName,字符串blobName){字符串headerResource = $"x-ms-blob-type:BlockBlob \ nx-ms-date:" + DateTime.UtcNow.ToString("R")+"\ nx-ms-version:2018-01-11";字符串urlResource ="/xyz/notes/test567";字符串stringToSign =方法+"\ n \ n \ n" + request.ContentLength +"\ n \ n" + request.ContentType +"\ n \ n \ n \ n \ n \ n \ n" + headerResource +"\ n" + urlResource;HMACSHA256 hmac =新的HMACSHA256(Convert.FromBase64String(storagekey));字符串签名= Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));;字符串AuthorizationHeader = String.Format("{0} {1}:{2}","SharedKey",storageAccount,签名);返回AuthorizationHeader;}}
您的代码有两个问题:
- 您使用的服务版本无效.最新的Storage Service REST API版本是
2017-04-17
,而不是2018-01-11
.更改该设置后,您将不会遇到400错误(但会出现403错误). -
在您的
headerResource
中,您正在生成一个新的日期/时间值,该值与x-ms-date
中的日期/时间值不同标头.因此,您将得到403错误.因此,基本上您的代码将是:字符串headerResource = $"x-ms-blob-type:BlockBlob \ nx-ms-date:" +现在+"\ nx-ms-version:2017-04-17";
我做了这两个修复,之后就可以上传数据了.
这是完整的代码:
公共静态无效UploadBlobWithRestAPI(){字符串storageKey ="ffFJwPXTqyYvRoubNQEti/aQUUMwn41BG3KDtl/yGpG4DR1eKaHRq6Bhbw ==";字符串storageAccount ="xyz";字符串containerName ="notes";字符串blobName ="test567";字符串方法="PUT";string sampleContent ="Lorem ipsum dolor sit amet,consectetur adipiscing elit.Nulla id euismod urna.int contentLength = Encoding.UTF8.GetByteCount(sampleContent);字符串requestUri = $"https://xyz.blob.core.windows.net/notes/test567";HttpWebRequest request =(HttpWebRequest)WebRequest.Create(requestUri);现在的字符串= 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",现在);request.Headers.Add("x-ms-blob-type","BlockBlob");request.Headers.Add("Authorization",AuthorizationHeader2(method,now,request,storageAccount,storageKey,containerName,blobName));使用(流requestStream = request.GetRequestStream()){requestStream.Write(Encoding.UTF8.GetBytes(sampleContent),0,contentLength);}使用(HttpWebResponse resp =(HttpWebResponse)request.GetResponse()){Console.WriteLine(resp.StatusCode.ToString());Console.ReadKey();}}公共静态字符串AuthorizationHeader2(字符串方法,现在的字符串,HttpWebRequest请求,字符串storageAccount,字符串storageKey,字符串containerName,字符串blobName){字符串headerResource = $"x-ms-blob-type:BlockBlob \ nx-ms-date:" +现在+"\ nx-ms-version:2017-04-17";字符串urlResource ="/xyz/notes/test567";字符串stringToSign =方法+"\ n \ n \ n" + request.ContentLength +"\ n \ n" + request.ContentType +"\ n \ n \ n \ n \ n \ n \ n" + headerResource +"\ n" + urlResource;HMACSHA256 hmac =新的HMACSHA256(Convert.FromBase64String(storagekey));字符串签名= Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));;字符串AuthorizationHeader = String.Format("{0} {1}:{2}","SharedKey",storageAccount,签名);返回AuthorizationHeader;}
I am trying to communicate with my Container on Azure Blob Storage through a console application. I cannot use the SDK hence REST is my only option. Language is C# with .NET 4.5.2.
I have tried these two codes and both return the same error
Azure rest API put blob On StackOverflow
Azure Blob Storage Part 5(Non-StackOverflow)
The error that I receive is 400 Bad Request
Has anybody else faced the same issue and successfully resolved it?
I have added a CORS rule with (*) for almost everything
The code is an exact duplicate of the two links hence I am not adding it here.
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;
}
}
There are two issues with your code:
- You're using an invalid service version. Latest Storage Service REST API version is
2017-04-17
and not2018-01-11
. Once you change that, you will not get 400 error (but you will get 403 error). In your
headerResource
, you are generating a new date/time value which would be different than the date/time value in yourx-ms-date
header. Because of this you will get 403 error. So essentially your code would be:string headerResource = $"x-ms-blob-type:BlockBlob\nx-ms-date:" + now + "\nx-ms-version:2017-04-17";
I made these two fixes and after that I was able to upload the data.
Here's the complete code:
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;
}
这篇关于来自C#的Azure BLOB存储REST调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!