user2948533
user2948533

Reputation: 1163

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.

Upvotes: 51

Views: 160865

Answers (7)

Amila Thennakoon
Amila Thennakoon

Reputation: 417

This is my approach its worked for me

WEP API Method

            [HttpGet]
            [Route("pdfReport")]
            public byte[] ReportMRWiseCurrentStatus()
            {
    
                byte[] resultsarray = _materialRequestReportService.ReportMRWiseCurrentStatus();
                return resultsarray;
            }

The Client

using (var client = new HttpClient())
            {
                var response = client.GetAsync(webApiUrl);
                if (response.Result.IsSuccessStatusCode)
                {

                    var result = response.Result.Content.ReadAsStringAsync().Result.Replace("\"", string.Empty);

                    var bytearray=Convert.FromBase64String(result);
                    System.IO.File.WriteAllBytes(@"C:\DB\newpdfAmila.pdf", bytearray);
                }

             }

Upvotes: 0

bertasoft
bertasoft

Reputation: 487

Change your controller with this and you'll get the same size that you send

[HttpPost]
[Route("SomeRoute")]
public FileStreamResult MyMethod([FromBody] string ID)
{
  byte[] mybytearray = db.getmybytearray(ID);
  return File(new MemoryStream(mybytearray), "application/octet-stream");
}

This is an issue https://github.com/aspnet/Mvc/issues/7926

Upvotes: 6

user5481197
user5481197

Reputation:

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

Upvotes: 25

Ranjan Singh
Ranjan Singh

Reputation: 1

From WEBAPI/Server end, pass the values like :

String base64 = Convert.ToBase64String(bytes);     //Convert to ToBase64String

and receive the values from client

response = client.GetAsync("URL/home/GetFIle?id=" + File_id).Result;

responseBody = await response.Content.ReadAsStringAsync();

mybytearray = Convert.FromBase64String(responseBody);    //Convert to FromBase64String

Upvotes: -1

jaideep darapuneni
jaideep darapuneni

Reputation: 89

Instead of this

mybytearray = response.Content.ReadAsByteArrayAsync().Result;//Here is the problem

Use this

string result=null;
result = response.Content.ReadAsStringAsync().Result.Replace("\"", string.Empty);
 mybytearray=Convert.FromBase64String(result);

response was returning the byte array as base64encoded.

Upvotes: 8

Wim Coenen
Wim Coenen

Reputation: 66733

HTTP is a text based protocol. edit: HTTP can transport raw bytes as well. Luaan's answer is better.

The returned byte array will be converted into text in some way, depending on how the MediaTypeFormatterCollection is set up on the server and on the format requested by the HTTP client with the Accept header. The bytes will typically be converted to text by base64-encoding. The response may also be packaged further into JSON or XML, but the ratio of the expected length (528) to the actual length (706) seems to indicate a simple base64 string.

On the client side, you are not looking at the original bytes but at the bytes of this text representation. I would try reading the data as a string with ReadAsStringAsync and inspect it to see what format it is in. Also look at the headers of the response.

You should then parse this text accordingly to get the original bytes, e.g. with Convert.FromBase64String.

Upvotes: 17

Luaan
Luaan

Reputation: 63732

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.

Upvotes: 98

Related Questions