0

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;
        }
3
  • application/octet-stream is not an image content-type. Commented Mar 23, 2022 at 3:19
  • requestStream.Write(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(imageContentBytes)) <-- This is very, very incorrect. Commented Mar 23, 2022 at 3:20
  • 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. Commented Mar 23, 2022 at 3:22

1 Answer 1

2

I believe the issue is coming because you are uploading an image (which is binary content) as a string which is corrupting the data.

Please try by changing the following:

int imageContentLength = (Encoding.UTF8.GetString(imageContentBytes)).Length;

to

int imageContentLength = imageContentBytes.Length;

and

using (Stream requestStream = request.GetRequestStream())
{
    requestStream.Write(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(imageContentBytes)), 0, imageContentLength);
}

to

using (Stream requestStream = request.GetRequestStream())
{
    requestStream.Write(imageContentBytes, 0, imageContentLength);
}

Also, please set the proper value for content type. Considering the file you are uploading is a JPEG image, please set the content type to image/jpeg instead of application/octet-stream. This will ensure that the image will be displayed correctly when loaded in a browser.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.