Reputation: 1163
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
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
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
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
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
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
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
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