How does an ASP.NET Web API controller return binary data?

Posted: (EET/GMT+2)

 

Assume you are writing an ASP.NET Web API controller with the aim of returning binary data with .NET 4.x, such as a PDF document or an PNG image. For brevity's sake, let's assume you have a controller action like this:

public class MyApiController : ApiController
{
    // GET api/
    public byte[] Get()
    {
        return new byte[] { 65, 66, 67 };
    }
}

Above, the byte array would present some real binary content, here just three bytes as an example. When the above controller is accessed through HTTP, the response looks like this:

Pragma: no-cache
Cache-Control: no-cache
Date: Wed, 15 Feb 2017 10:40:12 GMT
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 6
Content-Type: application/json; charset=utf-8
Expires: -1

"QUJD"

Notice how the binary data (byte array) is automatically serialized to Base64 format: "QUJD".

However, if you add a content type value manually to the controller and construct a HttpResponseMessage manually, you can more precisely control the output:

public HttpResponseMessage Get()
{
    HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new ByteArrayContent(new byte[] { 65, 66, 67 })
    };
    result.Content.Headers.ContentType = new MediaTypeHeaderValue(
         "application/octet-stream");
    return result;
}

With this code, the HTTP response looks like this:

Pragma: no-cache
Cache-Control: no-cache
Date: Wed, 15 Feb 2017 10:43:36 GMT
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Length: 3
Content-Type: application/octet-stream
Expires: -1

ABC

Notice how the Content-Type header has now changed, and there is no automatic Base64 encoding anymore.

Hope this helps!