Me sugirieron que debería usar FileResult para permitir a los usuarios descargar archivos de mi aplicación Asp.Net MVC. Pero los únicos ejemplos de esto que puedo encontrar siempre tienen que ver con los archivos de imagen (especificando el tipo de contenido image / jpeg).
Pero, ¿y si no puedo saber el tipo de archivo? Quiero que los usuarios puedan descargar prácticamente cualquier archivo del área de archivos de mi sitio.
Había leído un método para hacer esto (ver una publicación anterior para el código), que realmente funciona bien, excepto por una cosa: el nombre del archivo que aparece en el cuadro de diálogo Guardar como se concatena desde la ruta del archivo con guiones bajos ( folder_folder_file.ext). Además, parece que la gente piensa que debería devolver un FileResult en lugar de usar esta clase personalizada que encontré BinaryContentResult.
¿Alguien sabe la forma "correcta" de hacer tal descarga en MVC?
EDITAR: obtuve la respuesta (a continuación), pero pensé que debería publicar el código de trabajo completo si alguien más está interesado:
public ActionResult Download(string filePath, string fileName)
{
string fullName = Path.Combine(GetBaseDir(), filePath, fileName);
byte[] fileBytes = GetFile(fullName);
return File(
fileBytes, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
}
byte[] GetFile(string s)
{
System.IO.FileStream fs = System.IO.File.OpenRead(s);
byte[] data = new byte[fs.Length];
int br = fs.Read(data, 0, data.Length);
if (br != fs.Length)
throw new System.IO.IOException(s);
return data;
}
fuente
Response.ContentType = MimeMapping.GetMimeMapping(filePath);
, desde stackoverflow.com/a/22231074/4573839Respuestas:
Simplemente puede especificar el tipo MIME genérico de octeto-flujo:
fuente
ReadAllBytes
fue agregado años más tarde en una edición. ¿Por qué es esta mi segunda respuesta más votada? Oh bien.non-invocable member "File" cannot be used like a method.
El marco MVC admite esto de forma nativa. El controlador System.Web.MVC.Controller.File proporciona métodos para devolver un archivo por nombre / secuencia / matriz .
Por ejemplo, utilizando una ruta virtual al archivo, puede hacer lo siguiente.
fuente
Si está utilizando .NET Framework 4.5, entonces use MimeMapping.GetMimeMapping (string FileName) para obtener el tipo MIME para su archivo. Así es como lo he usado en mi acción.
fuente
Phil Haack tiene un buen artículo donde creó una clase de resultado de acción de descarga de archivo personalizado. Solo necesita especificar la ruta virtual del archivo y el nombre a guardar.
Lo usé una vez y aquí está mi código.
En mi ejemplo, estaba almacenando la ruta física de los archivos, así que utilicé este método auxiliar, que encontré en algún lugar que no recuerdo, para convertirlo en una ruta virtual
Aquí está la clase completa tomada del artículo de Phill Haack
fuente
Server.MapPath(this.VirtualPath)
), por lo que consumir esto directamente sin cambios es un poco ingenuo. Debe producir una alternativa que aceptePhysicalPath
dado que eso es lo que eventualmente se requiere y es lo que está almacenando. Esto sería mucho más seguro ya que ha asumido que la ruta física y la ruta relativa serían las mismas (excluyendo la raíz). Los archivos de datos a menudo se almacenan es App_Data. Esto no es accesible como una ruta relativa.Gracias a Ian Henry !
En caso de que necesite obtener un archivo de MS SQL Server , esta es la solución.
Donde AppModel es
EntityFramework
modelo y MyFiles presenta una tabla en su base de datos. FileData estávarbinary(MAX)
en la tabla MyFiles .fuente
es simple, solo dé su ruta física en el directorio Path con el nombre del archivo
fuente
fuente
if (string.IsNullOrWhiteSpace (fileName)) devuelve Contenido ("nombre de archivo no presente");
fuente
GetFile debería estar cerrando el archivo (o abriéndolo dentro de un uso). Luego puede eliminar el archivo después de la conversión a bytes; la descarga se realizará en ese búfer de bytes.
Entonces, en su método de descarga ...
fuente