asp.net-mvc diferencias - Devolver un archivo para ver / descargar en ASP.NET MVC




vs file (8)

Tuve problemas con la respuesta aceptada debido a que ningún tipo de sugerencia sobre la variable "documento": var document = ... Así que estoy publicando lo que funcionó para mí como una alternativa en caso de que alguien más tenga problemas.

public ActionResult DownloadFile()
{
    string filename = "File.pdf";
    string filepath = AppDomain.CurrentDomain.BaseDirectory + "/Path/To/File/" + filename;
    byte[] filedata = System.IO.File.ReadAllBytes(filepath);
    string contentType = MimeMapping.GetMimeMapping(filepath);

    var cd = new System.Net.Mime.ContentDisposition
    {
        FileName = filename,
        Inline = true,
    };

    Response.AppendHeader("Content-Disposition", cd.ToString());

    return File(filedata, contentType);
}

Estoy encontrando un problema al enviar archivos almacenados en una base de datos al usuario en ASP.NET MVC. Lo que quiero es una vista que muestre dos enlaces, uno para ver el archivo y permitir que el tipo MIME enviado al navegador determine cómo debe manejarse, y el otro para forzar una descarga.

Si elijo ver un archivo llamado SomeRandomFile.bak y el navegador no tiene un programa asociado para abrir archivos de este tipo, entonces no tengo ningún problema con el comportamiento predeterminado de la descarga. Sin embargo, si elijo ver un archivo llamado SomeRandomFile.pdf o SomeRandomFile.jpg quiero que el archivo simplemente se abra. Pero también quiero mantener un enlace de descarga a un lado para poder forzar una solicitud de descarga independientemente del tipo de archivo. ¿Esto tiene sentido?

He intentado FileStreamResult y funciona para la mayoría de los archivos, su constructor no acepta un nombre de archivo por defecto, por lo que a los archivos desconocidos se les asigna un nombre de archivo basado en la url (que no conoce la extensión para dar según el tipo de contenido). Si fuerzo el nombre del archivo especificándolo, pierdo la capacidad del navegador para abrir el archivo directamente y obtengo un aviso de descarga. Alguien más ha encontrado esto.

Estos son los ejemplos de lo que he probado hasta ahora.

//Gives me a download prompt.
return File(document.Data, document.ContentType, document.Name);

//Opens if it is a known extension type, downloads otherwise (download has bogus name and missing extension)
return new FileStreamResult(new MemoryStream(document.Data), document.ContentType);

//Gives me a download prompt (lose the ability to open by default if known type)
return new FileStreamResult(new MemoryStream(document.Data), document.ContentType) {FileDownloadName = document.Name};

¿Alguna sugerencia?


Para ver el archivo (txt por ejemplo):

return File("~/TextFileInRootDir.txt", MediaTypeNames.Text.Plain);

Para descargar el archivo (txt por ejemplo):

return File("~/TextFileInRootDir.txt", MediaTypeNames.Text.Plain, "TextFile.txt");

Nota: para descargar el archivo debemos pasar el argumento fileDownloadName.


El código que figura a continuación me funcionó para obtener un archivo pdf de un servicio de API y responder al navegador, espero que sirva de ayuda;

public async Task<FileResult> PrintPdfStatements(string fileName)
    {
         var fileContent = await GetFileStreamAsync(fileName);
         var fileContentBytes = ((MemoryStream)fileContent).ToArray();
         return File(fileContentBytes, System.Net.Mime.MediaTypeNames.Application.Pdf);
    }

Creo que esta respuesta es más limpia (basada en https://.com/a/3007668/550975 )

    public ActionResult GetAttachment(long id)
    {
        FileAttachment attachment;
        using (var db = new TheContext())
        {
            attachment = db.FileAttachments.FirstOrDefault(x => x.Id == id);
        }

        return File(attachment.FileData, "application/force-download", Path.GetFileName(attachment.FileName));
    }

La respuesta de Darin Dimitrov es correcta. Sólo una adición:

Response.AppendHeader("Content-Disposition", cd.ToString()); puede causar que el navegador no pueda procesar el archivo si su respuesta ya contiene un encabezado de "Disposición de contenido". En ese caso, es posible que desee utilizar:

Response.Headers.Add("Content-Disposition", cd.ToString());

public ActionResult Download()
{
    var document = ...
    var cd = new System.Net.Mime.ContentDisposition
    {
        // for example foo.bak
        FileName = document.FileName, 

        // always prompt the user for downloading, set to true if you want 
        // the browser to try to show the file inline
        Inline = false, 
    };
    Response.AppendHeader("Content-Disposition", cd.ToString());
    return File(document.Data, document.ContentType);
}

NOTA: este código de ejemplo anterior no tiene en cuenta correctamente los caracteres internacionales en el nombre del archivo. Ver RFC6266 para la estandarización relevante. Creo que las versiones recientes del método File() de ASP.Net MVC y la clase ContentDispositionHeaderValue adecuadamente. - Oskar 2016-02-25


Otra forma fácil es

public ActionResult GetLoadingLogo()
{
  if (1 == 1)
  {
    return new FilePathResult(Server.MapPath("~/Content/Images/ajaxLoader_dhanlaxmi.gif"), "image/gif");
  }
  else
  {
    return new FilePathResult(Server.MapPath("~/Content/Images/add-icon.png"), "image/png");
  }
}

Esto funcionó para mí. Desde que estoy almacenando imágenes en una base de datos de SQL Server.

    [HttpGet("/image/{uuid}")]
    public IActionResult GetImageFile(string uuid) {
        ActionResult actionResult = new NotFoundResult();
        var fileImage = _db.ImageFiles.Find(uuid);
        if (fileImage != null) {
            actionResult = new FileContentResult(fileImage.Data,
                fileImage.ContentType);
        }
        return actionResult;
    }

En el fragmento de _db.ImageFiles.Find(uuid) anterior _db.ImageFiles.Find(uuid) está buscando el registro del archivo de imagen en la base de datos (contexto EF). Devuelve un objeto FileImage que es solo una clase personalizada que hice para el modelo y luego lo usa como FileContentResult.

public class FileImage {
   public string Uuid { get; set; }
   public byte[] Data { get; set; }
   public string ContentType { get; set; }
}




asp.net-mvc asp.net-mvc-3 http-headers download