简体   繁体   中英

How to properly encode binary data to send over REST api PUT call

I'm trying to simply upload an image file to Azure blob store and the file is making it there but the file size is bigger than it should be and when I download the file via the browser it won't open as an image.

I manually uploaded the same file via the Azure interface and the file works and is 22k, uploading via my code is 29k and doesn't work.

NOTE: One thing to note is that all the examples used with this code only send text files. Maybe the Encoding.UTF8.GetBytes(requestBody); line is doing it?

This is where I'm Base64 encoding my data

HttpPostedFileBase hpf = Request.Files[file] as HttpPostedFileBase
byte[] binData;
using (BinaryReader b = new BinaryReader(hpf.InputStream))
    binData = b.ReadBytes(hpf.ContentLength);

var result = System.Convert.ToBase64String(binData);
new BlobHelper("STORENAMEHERE", "SECRETKEY").PutBlob("images", "test.jpg", result);

This is what I'm using to PUT the data, it's from https://azurestoragesamples.codeplex.com/

public bool PutBlob(string container, string blob, string content)
{
    return Retry<bool>(delegate()
    {
        HttpWebResponse response;

        try
        {
            SortedList<string, string> headers = new SortedList<string, string>();
            headers.Add("x-ms-blob-type", "BlockBlob");

            response = CreateRESTRequest("PUT", container + "/" + blob, content, headers).GetResponse() as HttpWebResponse;
            response.Close();
            return true;
        }
        catch (WebException ex)
        {
            if (ex.Status == WebExceptionStatus.ProtocolError &&
                ex.Response != null &&
                (int)(ex.Response as HttpWebResponse).StatusCode == 409)
                return false;

            throw;
        }
    });
}

public HttpWebRequest CreateRESTRequest(string method, string resource, string requestBody = null, SortedList<string, string> headers = null,
    string ifMatch = "", string md5 = "")
{
    byte[] byteArray = null;
    DateTime now = DateTime.UtcNow;
    string uri = Endpoint + resource;

    HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;
    request.Method = method;
    request.ContentLength = 0;
    request.Headers.Add("x-ms-date", now.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
    request.Headers.Add("x-ms-version", "2009-09-19");

    if (headers != null)
    {
        foreach (KeyValuePair<string, string> header in headers)
            request.Headers.Add(header.Key, header.Value);
    }

    if (!String.IsNullOrEmpty(requestBody))
    {
        request.Headers.Add("Accept-Charset", "UTF-8");

        byteArray = Encoding.UTF8.GetBytes(requestBody);
        request.ContentLength = byteArray.Length;
    }

    request.Headers.Add("Authorization", AuthorizationHeader(method, now, request, ifMatch, md5));

    if (!String.IsNullOrEmpty(requestBody))
        request.GetRequestStream().Write(byteArray, 0, byteArray.Length);

    return request;
}

I believe the problem is with how you're converting the binary data to string and then converting it back to byte array.

While converting binary data to string, you're using System.Convert.ToBase64String however while getting the byte array from string you're using Encoding.UTF8.GetBytes . Most likely this is causing the mismatch.

Please change the following line of code:

byteArray = Encoding.UTF8.GetBytes(requestBody);

to

byteArray = System.Convert.FromBase64String(requestBody);

and that should fix the problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM