Tenemos algunos archivos almacenados en la base de datos sql. En un formulario ASP.NET MVC3, mostramos 2 enlaces:Cómo evitar los encabezados duplicados de disposición de contenido con MVC3 FileContentResult?
Ver este archivo | Descargar este archivo
Estos enlaces van a estos métodos de acción correspondientes. La descarga funciona como se esperaba: al hacer clic en un enlace se fuerza un diálogo de guardar en el navegador. Sin embargo, la pantalla está causando que se envíen encabezados duplicados de Content-Disposition al navegador, lo que da como resultado un error en Chrome y una página vacía en Firefox.
[ActionName("display-file")]
public virtual ActionResult DisplayFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
Response.AddHeader("Content-Disposition",
string.Format("inline; filename={0}", file.Name));
return File(file.Content, file.MimeType, file.Name);
}
}
[ActionName("download-file")]
public virtual ActionResult DownloadFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
return File(file.Content, file.MimeType, file.Name);
}
}
Éstos son los 2 cabeceras enviadas al navegador para la acción de la pantalla:
Content-Disposition: inline; filename=name-of-my-file.pdf
Content-Disposition: attachment; filename="name-of-my-file.pdf"
He intentado cambiar mi cabecera content-disposition personalizada para envolver el nombre de archivo entre comillas dobles, pero aún así envió 2 encabezados para el navegador. También traté de eliminar el encabezado Content-Disposition antes de agregar el personalizado, pero parece que el encabezado del archivo adjunto se agrega después de que se devuelve FileContentResult.
Este código solía funcionar. Ejecuté una prueba ayer y noté que ya no funciona en Chrome o Firefox. Esto podría deberse a las actualizaciones en los navegadores. IE8 y Safari aún abren el archivo correctamente.
actualización
Gracias de nuevo Darin, que son correctas. De hecho, utilizamos este enfoque debido a another question you answered.
Un poco más de información acerca de cómo esto se resolvió en última instancia, por nuestra parte, tenemos una ruta personalizada para el enlace de archivo de pantalla:
context.MapRoute(null,
"path/to/display-file-attachment/{fileId}/{fileName}",
new
{
area = "AreaName",
controller = "ControllerName",
action = "DisplayFile",
}
);
El hipervínculo de la página pasa el nombre del archivo para el método de acción a través el parámetro de ruta, por lo que ya es parte de la URL. Por lo tanto, no fue necesario agregar un encabezado de disposición de contenido personalizado para que el nombre del archivo coincida con el del sistema cuando el usuario decidió descargarlo (al hacer clic en el icono Guardar en el visualizador de PDF del navegador). Así que sólo utilizamos esto:
[ActionName("display-file")]
public virtual ActionResult DisplayFile (Guid fileId, string fileName)
{
var file = _repos.GetFileInfo(fileId);
if (file != null)
{
// no custom content-disposition header, and no 3rd fileName argument
return File(file.Content, file.MimeType);
}
}
Firefox y Chrome de hecho se han vuelto más estrictas en el manejo de cabeceras Content-Disposition. –
@JulianReschke, ¿podría explicar los caracteres que no son ASCII? Todavía no hemos probado esto con caracteres Unicode en nombres de archivo. – danludwig
para nombres que no sean ASCII en C-D para "funcionar" en todos los navegadores, los servidores actualmente necesitan hacer sniffing User-Agent. Ver http://greenbytes.de/tech/tc2231/ y http://greenbytes.de/tech/webdav/rfc6266.html. Tengo mis dudas de que ASP.net lo haga bien, pero me encantaría saber lo contrario. –