I'm trying to upload an image to Azure storage container.
Using UploadBlobWithRestAPI, I'm trying to call the rest PUT API and using AuthorizationHeader, I'm trying to create the Authorization for the API call.
I'm getting the image created in the container. But, for some reason the image is not in the readable format. On downloading the image from container and trying to open in explorer, am getting "It appears that we don't support this file format". Any idea?
public void UploadBlobWithRestAPI(string MachineName,string ImageName)
{
string storageKey = "Storagekey";
string storageAccount = "Account";
string containerName = "test-container";
string blobName = "test2.jpg";
string method = "PUT";
Byte[] imageContentBytes = System.IO.File.ReadAllBytes(@"C:\\Test2.jpg");
int imageContentLength = (Encoding.UTF8.GetString(imageContentBytes)).Length;
string requestUri = $"https://{storageAccount}.blob.core.windows.net/{containerName}/{blobName}";
System.Net.HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
string now = DateTime.UtcNow.ToString("R");
request.Method = method;
request.ContentType = "application/octet-stream";
request.ContentLength = imageContentLength;
request.Headers.Add("x-ms-version", "2015-12-11");
request.Headers.Add("x-ms-date", now);
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, storageAccount, storageKey, containerName, blobName));
using (Stream requestStream = request.GetRequestStream())
{
requestStream.Write(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(imageContentBytes)), 0, imageContentLength);
}
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
MessageBox.Show(resp.StatusCode.ToString());
}
}
public string AuthorizationHeader(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:2015-12-11";
string urlResource = $"/{storageAccount}/{containerName}/{blobName}";
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;
}
application/octet-streamis not an image content-type.requestStream.Write(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(imageContentBytes))<-- This is very, very incorrect.System.IO.File.ReadAllBytes(@"C:\\Test2.jpg");<-- This is also incorrect. While I'll concede that it "works", it's only because Windows is being forgiving by eliding empty subdirectory names. You need to use either verbatim-strings (@"C:\Test2.jpg") or backslash-escapes ("C:\\Test2.jpg") - don't use both at the same time.