Blaise Blaise - 4 months ago 478
C# Question

How to return a file (FileContentResult) in ASP.NET WebAPI

In a regular MVC controller, we can output pdf with a

FileContentResult
.

public FileContentResult Test(TestViewModel vm)
{
var stream = new MemoryStream();
//... add content to the stream.

return File(stream.GetBuffer(), "application/pdf", "test.pdf");
}


But how can we change it into an
ApiController
?

[HttpPost]
public IHttpActionResult Test(TestViewModel vm)
{
//...
return Ok(pdfOutput);
}





Here is what I've tried but it doesn't seem to work.

[HttpGet]
public IHttpActionResult Test()
{
var stream = new MemoryStream();
//...
var content = new StreamContent(stream);
content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
content.Headers.ContentLength = stream.GetBuffer().Length;
return Ok(content);
}


The returned result displayed in the browser is:

{"Headers":[{"Key":"Content-Type","Value":["application/pdf"]},{"Key":"Content-Length","Value":["152844"]}]}


And there is a similar post on SO: Returning binary file from controller in ASP.NET Web API
. It talks about output an existing file. But I could not make it work with a stream.

Any suggestions?

Answer

Here is what I found:

Instead of returning StreamContent as the Content, I can make it work with ByteArrayContent.

[HttpGet]
public HttpResponseMessage Generate()
{
    var stream = new MemoryStream();
    // processing the stream.

    var result = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new ByteArrayContent(stream.GetBuffer())
    };
    result.Content.Headers.ContentDisposition =
        new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
    {
        FileName = "CertificationCard.pdf"
    };
    result.Content.Headers.ContentType =
        new MediaTypeHeaderValue("application/octet-stream");

    return result;
}