locked
Azure Blob REST API - ContentType RRS feed

  • Question

  • I am having tough time setting content type when uploading via REST APIs. They all seem to be uploaded using the default application/octet-stream.

    Here's a snippet of what I am doing:

    --

    String requestUri = string.Format("https://{0}.blob.core.windows.net/$web/{1}/{2}", storageAccountName, containerName, blobName);
    
                using (var httpRequestMessage = new HttpRequestMessage(HttpMethod.Get, requestUri)
                { Content = (requestPayload == null) ? null : new ByteArrayContent(requestPayload) })
                {
                    var now = DateTime.UtcNow;
    
                    httpRequestMessage.Method = HttpMethod.Put;                
                    httpRequestMessage.Headers.Add("Content-Type", "text/plain; charset=UTF-8");
                    httpRequestMessage.Headers.Add("ContentLength", contentLength.ToString());
                    httpRequestMessage.Headers.Add("x-ms-version", "2017-04-17");
                    httpRequestMessage.Headers.Add("x-ms-date", now.ToString("R"));
                    httpRequestMessage.Headers.Add("x-ms-blob-type", "BlockBlob");

    I understand that content-type should be set to the Content field. So tried below modification and that did not work. What am I doing wrong?

    httpRequestMessage.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");

    --

    Thursday, January 10, 2019 11:48 PM

Answers

  • After poking around I noticed that the specific error after adding content type header was:

    StatusCode: 403, ReasonPhrase: 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.'

    After spending time on internet, I came across this link: https://stackoverflow.com/questions/30216162/azure-storage-failed-to-upload-image-if-set-contenttype-using-rest

    Adding content-type to the signingstring solved the issue:

    internal static AuthenticationHeaderValue GetAuthorizationHeader(
               string storageAccountName, string storageAccountKey, DateTime now,
               HttpRequestMessage httpRequestMessage, string ifMatch = "", string md5 = "", string contenttype = "application/octet-stream")
            {
                // This is the raw representation of the message signature.
                HttpMethod method = httpRequestMessage.Method;
                String MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n{6}\n\n\n{2}\n\n\n\n{3}{4}",
                          method.ToString(),
                          (method == HttpMethod.Get || method == HttpMethod.Head) ? String.Empty
                            : httpRequestMessage.Content.Headers.ContentLength.ToString(),
                          ifMatch,
                          GetCanonicalizedHeaders(httpRequestMessage),
                          GetCanonicalizedResource(httpRequestMessage.RequestUri, storageAccountName),
                          md5,contenttype);

    • Marked as answer by diffident Friday, January 11, 2019 4:32 PM
    Friday, January 11, 2019 4:32 PM

All replies

  • Just for clarification: Have you tried the suggestion mentioned in this article?

    Friday, January 11, 2019 12:51 PM
  • After poking around I noticed that the specific error after adding content type header was:

    StatusCode: 403, ReasonPhrase: 'Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.'

    After spending time on internet, I came across this link: https://stackoverflow.com/questions/30216162/azure-storage-failed-to-upload-image-if-set-contenttype-using-rest

    Adding content-type to the signingstring solved the issue:

    internal static AuthenticationHeaderValue GetAuthorizationHeader(
               string storageAccountName, string storageAccountKey, DateTime now,
               HttpRequestMessage httpRequestMessage, string ifMatch = "", string md5 = "", string contenttype = "application/octet-stream")
            {
                // This is the raw representation of the message signature.
                HttpMethod method = httpRequestMessage.Method;
                String MessageSignature = String.Format("{0}\n\n\n{1}\n{5}\n{6}\n\n\n{2}\n\n\n\n{3}{4}",
                          method.ToString(),
                          (method == HttpMethod.Get || method == HttpMethod.Head) ? String.Empty
                            : httpRequestMessage.Content.Headers.ContentLength.ToString(),
                          ifMatch,
                          GetCanonicalizedHeaders(httpRequestMessage),
                          GetCanonicalizedResource(httpRequestMessage.RequestUri, storageAccountName),
                          md5,contenttype);

    • Marked as answer by diffident Friday, January 11, 2019 4:32 PM
    Friday, January 11, 2019 4:32 PM
  • Thanks for sharing this information. It should certainly help those with a scenario like yours. 
    Friday, January 11, 2019 5:04 PM