monkeyhouse
monkeyhouse

Reputation: 2896

Receive, send file over Web Api

I'm trying to write a WebApi service that receives a file, does a trivial manipulation, and sends the file back. I'm having issues on sending and/or receiving the file from the service.

The issue I'm having is that the file returned from the service is ~1.5x larger than the manipulated file, e.g. when the file is returned it's like 300kb instead of the 200kb it should be.

I assume its being wrapped and or manipulated somehow, and I'm unsure of how to receive it properly. The code for the WebAPI service and the method that calls the web service are included below

In, the WebApi service, when I hit the line return Ok(bufferResult), the file is a byte[253312]

In the method that calls the web service, after the file is manipulated and returned, following the line var content = stream.Result;, the stream has a length of 337754 bytes.

Web API service code

public ConversionController: APIController{
  public async Task<IHttpActionResult> TransformImage()
   {
    if (!Request.Content.IsMimeMultipartContent())
        throw new Exception();

    var provider = new MultipartMemoryStreamProvider();
    await Request.Content.ReadAsMultipartAsync(provider);

    var file = provider.Contents.First();
    var filename = file.Headers.ContentDisposition.FileName.Trim('\"');
    var buffer = await file.ReadAsByteArrayAsync();
    var stream = new MemoryStream(buffer);

// [file manipulations omitted;]
    // [the result is populated into a MemoryStream named response ]

    //debug : save memory stream to disk to make sure tranformation is successfull
    /*response.Position  = 0;
      path = @"C:\temp\file.ext";
      using (var fileStream = System.IO.File.Create(path))
      {
        saveStream.CopyTo(fileStream);
      }*/


    var bufferResult = response.GetBuffer();
    return Ok(bufferResult);
   }
}

Method Calling the Service

public async Task<ActionResult> AsyncConvert()
    {

    var url = "http://localhost:49246/api/conversion/transformImage";   
var filepath = "drive/file/path.ext";
    HttpContent fileContent = new ByteArrayContent(System.IO.File.ReadAllBytes(filepath));

    using (var client = new HttpClient())
    {
        using (var formData = new MultipartFormDataContent())
        {
            formData.Add(fileContent, "file", "fileName");

    //call service
            var response = client.PostAsync(url, formData).Result;

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception();
            }
            else
            {

                if (response.Content.GetType() != typeof(System.Net.Http.StreamContent))
                    throw new Exception();

                var stream = response.Content.ReadAsStreamAsync();
                var content = stream.Result;

                var path = @"drive\completed\name.ext";
                using (var fileStream = System.IO.File.Create(path))
                {
                    content.CopyTo(fileStream);  
                }
            }
        }


    }

    return null;
}

I'm still new to streams and WebApi, so I may be missing something quite obvious. Why are the file streams different sizes? (eg. is it wrapped and how do I unwrap and/or receive the stream)

Upvotes: 8

Views: 22725

Answers (1)

monkeyhouse
monkeyhouse

Reputation: 2896

okay, to receive the file correctly, I needed to replace the line

var stream = response.Content.ReadAsStreamAsync();

with

var contents = await response.Content.ReadAsAsync<Byte[]>();

to provide the correct type for the binding

so, the later part of the methods that calls the service looks something like

var content = await response.Content.ReadAsAsync<Byte[]>();
var saveStream = new MemoryStream(content);
saveStream.Position = 0;

//Debug: save converted file to disk
/*
var path = @"drive\completed\name.ext";
using (var fileStream = System.IO.File.Create(path))
{
     saveStream.CopyTo(fileStream);  
}*/

Upvotes: 6

Related Questions