How to Get byte array properly from an Web Api Method in C#?

I have the following controller method:

[HttpPost]
[Route("SomeRoute")]
public byte[] MyMethod([FromBody] string ID)
{
  byte[] mybytearray = db.getmybytearray(ID);//working fine,returning proper result.
  return mybytearray;
}

Now in the calling method(thats also another WebApi method!) I have written like this:

private HttpClient client = new HttpClient ();
private HttpResponseMessage response = new HttpResponseMessage ();
byte[] mybytearray = null;
response = client.GetAsync(string.Format("api/ABC/MyMethod/{0}", ID)).Result;
if (response.IsSuccessStatusCode)
{
    mybytearray = response.Content.ReadAsByteArrayAsync().Result;//Here is the problem
} 

Now, the problem is the byte array MyMethod is sending is of 528 bytes, but here after making ReadAsByteArrayAsync, the size becomes larger(706 bytes) and the values are also goofed up.


Solution 1:

Actually, HTTP can handle "raw" binary as well - the protocol itself is text based, but the payload can be binary (see all those files you download from the internet using HTTP).

There is a way to do this in WebApi - you just have to use StreamContent or ByteArrayContent as the content, so it does involve some manual work:

public HttpResponseMessage ReturnBytes(byte[] bytes)
{
  HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
  result.Content = new ByteArrayContent(bytes);
  result.Content.Headers.ContentType = 
      new MediaTypeHeaderValue("application/octet-stream");

  return result;
}

It may be possible to do the same thing using some attribute or something, but I don't know how.

Solution 2:

response.Content.ReadAsAsync<byte[]>().Result //Put this code in your client.

I want to make it clear that ReadAsAsync<byte[]>() and ReadAsByteArrayAsync() do NOT act the same.

ReadAsByteArrayAsync() turns everything into a Base64 Byte Array. It doesn't get the non-Base64 byte[] from response.Content but ReadAsAsync<byte[]>() does