2

I need create POST request from WinRT app,which should contain StorageFile. I need to do this exactly in style like this : post request with file inside body. Is it possible? I know about HttpClient.PostAsync(..), but I can't put StorageFile inside request body. I want to send mp3 file to Web Api

On server side I get file like this:

[System.Web.Http.HttpPost]
        public HttpResponseMessage UploadRecord([FromUri]string filename)
        {
            HttpResponseMessage result = null;
            var httpRequest = HttpContext.Current.Request;
            if (httpRequest.Files.Count > 0)
            {
                foreach (string file in httpRequest.Files)
                {
                    var postedFile = httpRequest.Files[file];
                    var filePath = HttpContext.Current.Server.MapPath("~/Audio/" + filename + ".mp3");
                    postedFile.SaveAs(filePath);
                }
                result = Request.CreateResponse(HttpStatusCode.Created);
            }
            else
            {
                result = Request.CreateResponse(HttpStatusCode.BadRequest);
            }

            return result;
        }
Nathan Phillips
  • 11,899
  • 1
  • 31
  • 24
ivamax9
  • 2,601
  • 24
  • 33

3 Answers3

1

You can send it as a byte[] using the ByteArrayContent class as a second parameter:

StroageFile file = // Get file here..
byte[] fileBytes = null;
using (IRandomAccessStreamWithContentType stream = await file.OpenReadAsync())
{
    fileBytes = new byte[stream.Size];
    using (DataReader reader = new DataReader(stream))
    {
        await reader.LoadAsync((uint)stream.Size);
        reader.ReadBytes(fileBytes);
    }
}

var httpClient = new HttpClient();
var byteArrayContent = new ByteArrayContent(fileBytes);

await httpClient.PostAsync(address, fileBytes);
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • Hi,Yuval. HttpClient dont have overload with ByteArrayContent. – ivamax9 Jun 09 '14 at 13:23
  • thank you, but it not helped, I added server side code for example how I get file from request. – ivamax9 Jun 09 '14 at 14:13
  • It didn't help because your server side code is reading files the wrong way. Take a look at this: http://stackoverflow.com/questions/15543150/httprequest-files-is-empty-when-posting-file-through-httpclient – Yuval Itzchakov Jun 09 '14 at 14:27
0

If you're uploading files of any appreciable size, then it's best to use the Background Transfer API so that the upload doesn't get paused if the app is suspended. Specifically see BackgroundUploader.CreateUpload which takes a StorageFile directly. Refer to the Background Transfer sample for both the client and server sides of this relationship, as the sample also includes a sample server.

  • Hi,I tried running this example, but something strange with this it. Example always stopped work on line `UploadOperation upload = uploader.CreateUpload(uri, file);` Sad, but I dont know why it happening and server side work great... – ivamax9 Jun 09 '14 at 22:08
  • Don't know why that would be happening (it's not an async call either). I can only think that perhaps the file is corrupt or something. – Kraig Brockschmidt - MSFT Jun 10 '14 at 01:33
0

To use less memory you can pipe the file stream to the HttpClient stream directly.

    public async Task UploadBinaryAsync(Uri uri)
    {
        var openPicker = new FileOpenPicker();
        StorageFile file = await openPicker.PickSingleFileAsync();
        if (file == null)
            return;
        using (IRandomAccessStreamWithContentType fileStream = await file.OpenReadAsync())
        using (var client = new HttpClient())
        {
            try
            {
                var content = new HttpStreamContent(fileStream);
                content.Headers.ContentType =
                    new HttpMediaTypeHeaderValue("application/octet-stream");
                HttpResponseMessage response = await client.PostAsync(uri, content);
                _ = response.EnsureSuccessStatusCode();
            }
            catch (Exception ex)
            {
                // Handle exceptions appropriately
            }
        }
    }
Nathan Phillips
  • 11,899
  • 1
  • 31
  • 24