Returning binary file from controller in ASP.NET Web API
asp.net, asp.net-mvc, asp.net-web-api
Solution
Try using a simple `HttpResponseMessage` with its `Content` property set to a `StreamContent`:
// using System.IO;
// using System.Net.Http;
// using System.Net.Http.Headers;
public HttpResponseMessage Post(string version, string environment,
string filetype)
{
var path = @"C:\Temp\test.exe";
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(path, FileMode.Open, FileAccess.Read);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/octet-stream");
return result;
}
A few things to note about the `stream` used:
You must not call `stream.Dispose()`, since Web API still needs to be able to access it when it processes the controller method's `result` to send data back to the client. Therefore, do not use a `using (var stream = …)` block. Web API will dispose the stream for you.
Make sure that the stream has its current position set to 0 (i.e. the beginning of the stream's data). In the above example, this is a given since you've only just opened the file. However, in other scenarios (such as when you first write some binary data to a `MemoryStream`), make sure to `stream.Seek(0, SeekOrigin.Begin);` or set `stream.Position = 0;`
With file streams, explicitly specifying `FileAccess.Read` permission can help prevent access rights issues on web servers; IIS application pool accounts are often given only read / list / execute access rights to the wwwroot.
Problem
I'm working on a web service using ASP.NET MVC's new WebAPI that will serve up binary files, mostly `.cab` and `.exe` files. The following controller method seems to work, meaning that it returns a file, but it's setting the content type to `application/json`: ``` public HttpResponseMessage<Stream> Post(string version, string environment, string filetype) { var path = @"C:\Temp\test.exe"; var stream = new FileStream(path, FileMode.Open); return new HttpResponseMessage<Stream>(stream, new MediaTypeHeaderValue("application/octet-stream")); } ``` Is there a better way to do this?