Estoy trabajando en un servicio web utilizando el nuevo WebAPI de ASP.NET MVC que servirá archivos binarios, principalmente .cab
y .exe
archivos.
El siguiente método de controlador parece funcionar, lo que significa que devuelve un archivo, pero establece el tipo de contenido en 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"));
}
¿Hay una mejor manera de hacer esto?
asp.net
asp.net-mvc
asp.net-web-api
Josh Earl
fuente
fuente
Respuestas:
Intente usar un simple
HttpResponseMessage
con suContent
propiedad establecida en aStreamContent
:Algunas cosas a tener en cuenta sobre el
stream
uso:No debe llamar
stream.Dispose()
, ya que la API web aún necesita poder acceder a ella cuando procesa los métodos del controladorresult
para enviar datos al cliente. Por lo tanto, no use unusing (var stream = …)
bloque. La API web eliminará la transmisión por usted.Asegúrese de que la secuencia tenga su posición actual establecida en 0 (es decir, el comienzo de los datos de la secuencia). En el ejemplo anterior, esto es un hecho dado que acaba de abrir el archivo. Sin embargo, en otros escenarios (como cuando escribe por primera vez algunos datos binarios en a
MemoryStream
), asegúrese destream.Seek(0, SeekOrigin.Begin);
establecerstream.Position = 0;
Con las secuencias de archivos, la especificación explícita de
FileAccess.Read
permisos puede ayudar a prevenir problemas de derechos de acceso en servidores web; Las cuentas del grupo de aplicaciones IIS a menudo solo tienen derechos de acceso de lectura / lista / ejecución para wwwroot.fuente
using
a ni al resultado (HttpResponseMessage
) ni a la secuencia en sí, ya que aún se usarán fuera del método. Como @Dan mencionó, el marco los elimina después de que haya terminado de enviar la respuesta al cliente.Para Web API 2 , puede implementar
IHttpActionResult
. Aquí está el mío:Entonces algo como esto en su controlador:
Y aquí hay una forma en que puede decirle a IIS que ignore las solicitudes con una extensión para que la solicitud llegue al controlador:
fuente
async
modificador en la firma del método y eliminar la creación de una tarea por completo: gist.github.com/ronnieoverby/ae0982c7832c531a9022Para aquellos que usan .NET Core:
Puede hacer uso de la interfaz IActionResult en un método de controlador API, así ...
Este ejemplo está simplificado, pero debería transmitir el punto. En .NET Core este proceso es tan mucho más simple que en las versiones anteriores de .NET - es decir, ningún tipo respuesta del ajuste, el contenido, los encabezados, etc.
Además, por supuesto, el tipo MIME para el archivo y la extensión dependerán de las necesidades individuales.
Referencia: SO Publicar respuesta por @NKosi
fuente
Si bien la solución sugerida funciona bien, hay otra forma de devolver una matriz de bytes desde el controlador, con el flujo de respuesta correctamente formateado:
Desafortunadamente, WebApi no incluye ningún formateador para "application / octet-stream". Aquí hay una implementación en GitHub: BinaryMediaTypeFormatter (hay pequeñas adaptaciones para que funcione en webapi 2, las firmas de los métodos cambiaron).
Puede agregar este formateador a su configuración global:
WebApi ahora debería usar
BinaryMediaTypeFormatter
si la solicitud especifica el encabezado correcto de aceptación.Prefiero esta solución porque un controlador de acción que devuelve el byte [] es más cómodo de probar. Sin embargo, la otra solución le permite un mayor control si desea devolver otro tipo de contenido que "application / octet-stream" (por ejemplo, "image / gif").
fuente
Para cualquiera que tenga el problema de que se llame a la API más de una vez mientras descarga un archivo bastante grande utilizando el método en la respuesta aceptada, establezca el búfer de respuesta en verdadero System.Web.HttpContext.Current.Response.Buffer = true;
Esto asegura que todo el contenido binario se almacena en el lado del servidor antes de enviarlo al cliente. De lo contrario, verá que se envían varias solicitudes al controlador y, si no lo maneja correctamente, el archivo se dañará.
fuente
Buffer
propiedad ha quedado en desuso a favor deBufferOutput
. Por defecto estrue
.La sobrecarga que está utilizando establece la enumeración de los formateadores de serialización. Debe especificar el tipo de contenido explícitamente como:
fuente
Content Type: application/json
en Fiddler. ElContent Type
parece estar configurado correctamente si rompo antes de devolver lahttpResponseMessage
respuesta. ¿Alguna idea más?Tu podrías intentar
fuente