send byte array by HTTP POST in store app

Essah picture Essah · May 7, 2014 · Viewed 52.5k times · Source

I'm trying to send some images + some meta data to a server by HTTP post from a windows store app but get stuck when trying to actually include the data in the post. It cannot be done the way you would accomplish this in a windows forms app or similar due to the changes to the store app API.

I get the error.

cannot convert source type byte[] to target type System.Net.Http.httpContent

now this is obviously because it's 2 different types that can't be implicitly casted, but it's basically what I'm looking to be able to do. How do I make get my byte array data into the httpContent type so I can include it in the following call

httpClient.PostAsync(Uri uri,HttpContent content);

here's my full upload method:

async private Task UploadPhotos(List<Photo> photoCollection, string recipient, string format)
    {
        PhotoDataGroupDTO photoGroupDTO = PhotoSessionMapper.Map(photoCollection);

        try
        {
            var client = new HttpClient();
            client.MaxResponseContentBufferSize = 256000;
            client.DefaultRequestHeaders.Add("Upload", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");

            // POST action_begin
            const string actionBeginUri = "http://localhost:51139/PhotoService.axd?action=Begin";
            HttpResponseMessage response = await client.GetAsync(actionBeginUri);
            response.EnsureSuccessStatusCode();
            string responseBodyAsText = await response.Content.ReadAsStringAsync();
            string id = responseBodyAsText;
            ////

            // POST action_upload
            Uri actionUploadUri = new Uri("http://localhost:51139/PhotoService.axd?action=Upload&brand={0}&id={1}&name={2}.jpg");

            var metaData = new Dictionary<string, string>()
            {
                {"Id", id},
                {"Brand", "M3rror"}, //TODO: Denne tekst skal komme fra en konfigurationsfil.
                {"Format", format},
                {"Recipient", recipient}
            };

            string stringData = "";
            foreach (string key in metaData.Keys)
            {
                string value;
                metaData.TryGetValue(key, out value);
                stringData += key + "=" + value + ",";
            }

            UTF8Encoding encoding = new UTF8Encoding();
            byte[] byteData = encoding.GetBytes(stringData);

            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, actionUploadUri);

            // send meta data
            // TODO get byte data in as content
            HttpContent metaDataContent = byteData;
            HttpResponseMessage actionUploadResponse = await client.PostAsync(actionUploadUri, metaDataContent);

            actionUploadResponse.EnsureSuccessStatusCode();
            responseBodyAsText = await actionUploadResponse.Content.ReadAsStringAsync();

            // send photos
            // TODO get byte data in as content
            foreach (byte[] imageData in photoGroupDTO.PhotosData)
            {
                HttpContent imageContent = imageData;
                actionUploadResponse = await client.PostAsync(actionUploadUri, imageContent);
                actionUploadResponse.EnsureSuccessStatusCode();
                responseBodyAsText = await actionUploadResponse.Content.ReadAsStringAsync();
            }                
            ////

            // POST action_complete
            const string actionCompleteUri = "http://localhost:51139/PhotoService.axd?action=Complete";
            HttpResponseMessage actionCompleteResponse = await client.GetAsync(actionCompleteUri);
            actionCompleteResponse.EnsureSuccessStatusCode();
            responseBodyAsText = await actionCompleteResponse.Content.ReadAsStringAsync();
            ////
        }

        catch (HttpRequestException e)
        {
        }
        catch (Exception e)
        {
            Debug.WriteLine(e.ToString());
        }
    }

Answer

kiewic picture kiewic · May 8, 2014

It will be more straightforward to use System.Net.Http.ByteArrayContent. E.g:

// Converting byte[] into System.Net.Http.HttpContent.
byte[] data = new byte[] { 1, 2, 3, 4, 5};
ByteArrayContent byteContent = new ByteArrayContent(data);
HttpResponseMessage reponse = await client.PostAsync(uri, byteContent);

For text only with an specific text encoding use:

// Convert string into System.Net.Http.HttpContent using UTF-8 encoding.
StringContent stringContent = new StringContent(
    "blah blah",
    System.Text.Encoding.UTF8);
HttpResponseMessage reponse = await client.PostAsync(uri, stringContent);

Or as you mentioned above, for text and images using multipart/form-data:

// Send binary data and string data in a single request.
MultipartFormDataContent multipartContent = new MultipartFormDataContent();
multipartContent.Add(byteContent);
multipartContent.Add(stringContent);
HttpResponseMessage reponse = await client.PostAsync(uri, multipartContent);