How to Get byte array properly from an Web Api Method in C#?
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.
Byte array different from an Web Api Method in C#?
With the given information I think it must have something to do with content negotiation. I can't tell the reason, but what I'm sure it's that there is a different approach to serve files behind a Web Api.
var response = Request.CreateResponse(HttpStatusCode.OK);
var stream = new FileStream(pathToFile, FileMode.Open, FileAccess.Read);
response.Content = new StreamContent(stream);
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
return ResponseMessage(response);
With this solution, you serve the file contents returning an IHttpActionResult
instance. And, returning a response with StreamContent
you are returning a stream that must not be modified by Web Api Content Negotation.
Returning byte array from server is different when received by the client
Since you are getting the response as string, just decode that Base64 string.
var result = response.Content.ReadAsStringAsync().Result;
byte[] actualBytes = Convert.FromBase64String(result);
return bytearray as file via API with C#
use below code
localFilePath = "file path";
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StreamContent(new FileStream(filepath, FileMode.Open, FileAccess.Read));
response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
response.Content.Headers.ContentDisposition.FileName = fileName;
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf or set your content type");
return response;
MVC or Web API transfer byte[] the most efficient approach
What is the correct way to pass a byte array
The easiest way of reading a byte[]
from WebAPI without writing custom MediaTypeFormatter for "application/octet-stream" is by simply reading it from the request stream manually:
[HttpPost]
public async Task<JsonResult> UploadFiles()
{
byte[] bytes = await Request.Content.ReadAsByteArrayAsync();
}
In another post, I described how to utilize the built in formatter for BSON (Binary JSON) which exists in WebAPI 2.1.
If you do want to go down the read and write a BinaryMediaTypeFormatter
which answers "application/octet-stream", a naive implementation would look like this:
public class BinaryMediaTypeFormatter : MediaTypeFormatter
{
private static readonly Type supportedType = typeof(byte[]);
public BinaryMediaTypeFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
}
public override bool CanReadType(Type type)
{
return type == supportedType;
}
public override bool CanWriteType(Type type)
{
return type == supportedType;
}
public override async Task<object> ReadFromStreamAsync(Type type, Stream stream,
HttpContent content, IFormatterLogger formatterLogger)
{
using (var memoryStream = new MemoryStream())
{
await stream.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
}
public override Task WriteToStreamAsync(Type type, object value, Stream stream,
HttpContent content, TransportContext transportContext)
{
if (value == null)
throw new ArgumentNullException("value");
if (!type.IsSerializable)
throw new SerializationException(
$"Type {type} is not marked as serializable");
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, value);
return Task.FromResult(true);
}
}
How to download file from bytes by using web api and angular
Angular's HttpClient assumes that the respose is JSON by default. If the response from your API is a text string, set the responseType
property of the HTTP request options (the third argument to httpService.post
) to "text"
. If the response is binary data, set the response type to "arraybuffer"
or "blob"
.
Related Topics
How to Get the Correct Ip from Http_X_Forwarded_For If It Contains Multiple Ip Addresses
Why Doesn't Mutex Get Released When Disposed
Validating for Large Files Upon Upload
Is It There Any Lru Implementation of Idictionary
Check If List<T> Contains Any of Another List
What Is the Command to Exit a Console Application in C#
How Can One Generate and Save a File Client Side Using Blazor
What's the Role of Gethashcode in the Iequalitycomparer<T> in .Net
Deserializing Heterogenous JSON Array into Covariant List<> Using JSON.Net
Why Use a Using Statement with a SQLtransaction
Companyname.Foo' Is a 'Namespace' But Is Used Like a 'Type'
Strings Sent Through Web API's Gets Wrapped in Quotes
Create a .Txt File If Doesn't Exist, and If It Does Append a New Line
How to Get Date and Time Formats Based on Culture Info
How to Suppress a Dialog Box Displayed by Code That I Can't Change
Add Custom Header in Httpwebrequest
Format a Number with Commas and Decimals in C# (ASP.NET MVC3)