Unicode en la cabecera Content-Disposition
-
23-09-2019 - |
Pregunta
Estoy utilizando HttpContext objeto implementado en HttpHandler hijo para descargar un archivo, cuando tengo caracteres no ASCII en el nombre de archivo se ve raro en IE mientras que se ve bien en Firefox.
a continuación es el código: -
context.Response.ContentType = ".cs";
context.Response.AppendHeader("Content-Length", data.Length.ToString());
context.Response.AppendHeader("Content-Disposition", String.Format("attachment; filename={0}",filename));
context.Response.OutputStream.Write(data, 0, data.Length);
context.Response.Flush();
cuando yo proporciono 'ay' 'ä' 'A¶' 'ü' '³' 'ay' 'ä' 'A¶' 'ü' '³' en el campo de nombre de archivo se ve diferente de lo que yo tiene en el nombre del archivo que se ve bien en Firefox. añadiendo EncodingType y juego de caracteres ha sido de ninguna utilidad.
En es decir, es 'Ãâ' 'ä' 'ö' 'ü' 'ó' 'Ãâ' 'ä' 'ö' 'ü' _ 'ó' y en Firefox es 'ay' 'ä' 'A¶' 'ü' '³' 'ay' 'ä ' 'A¶' 'ü' '³'.
alguna idea de cómo esto se puede solucionar?
Solución
he tenido un problema similar. Usted tiene que utilizar HttpUtility.UrlEncode o < a href = "http://msdn.microsoft.com/en-us/library/ms525738.aspx" rel = "noreferrer"> Server.URLEncode para codificar el nombre de archivo. También recuerdo Firefox no lo necesitaba. Moreoverit arruinado nombre del archivo cuando se de una URL codificada. Mi código:
// IE needs url encoding, FF doesn't support it, Google Chrome doesn't care
if (Request.Browser.IsBrowser ("IE"))
{
fileName = Server.UrlEncode(fileName);
}
Response.Clear ();
Response.AddHeader ("content-disposition", String.Format ("attachment;filename=\"{0}\"", fileName));
Response.AddHeader ("Content-Length", data.Length.ToString (CultureInfo.InvariantCulture));
Response.ContentType = mimeType;
Response.BinaryWrite(data);
Editar
He leído la especificación con más cuidado. En primer lugar los estados RFC2183 que:
Current [RFC 2045] gramática Restringe parámetros valores (y por tanto Content-Disposition nombres de archivo) a US-ASCII.
Pero luego me encontré referencias que [RFC 2045] es absolete y uno debe hacer referencia a RFC 2231 , que establece:
Los asteriscos ( "*") se reutilizan para proporcionar el indicador de que el lenguaje y información de juego de caracteres está presente y se utiliza la codificación. Un único comillas ( """) se utiliza para delimitar el conjunto de caracteres y la información de idioma al comienzo del parámetro valor. Signos de porcentaje ( "%") se utilizan como la bandera de codificación, que está de acuerdo con RFC 2047.
lo que significa que se puede utilizar UrlEncode de los símbolos no ASCII, siempre y cuando incluya la codificación como se indica en el RFC . He aquí un ejemplo:
string.Format("attachment; filename=\"{0}\"; filename*=UTF-8''{0}", Server.UrlEncode(fileName, Encoding.UTF8));
Tenga en cuenta que filename
se incluye, además de filename*
para la compatibilidad hacia atrás. También puede elegir otra codificación y modificar el parámetro en consecuencia, pero UTF-8 cubre todo.
Otros consejos
HttpUtility.UrlPathEncode podría ser una mejor opción. Como URLEncode sustituirá a los locales con signos '+'.
Para mí esta solución está trabajando en todos los principales navegadores:
Response.AppendHeader("Content-Disposition", string.Format("attachment; filename*=UTF-8''{0}", HttpUtility.UrlPathEncode(fileName).Replace(",", "%2C"));
var mime = MimeMapping.GetMimeMapping(fileName);
return File(fileName, mime);
Uso de ASP.NET MVC 3.
El Replace es necesario, porque Chrome no le gusta coma (,) en valores de los parámetros: http://www.gangarasa.com/lets-Do-GoodCode/tag/err_response_headers_multiple_content_disposition/
Es posible que desee leer RFC 6266 y vistazo a las pruebas a http://greenbytes.de/tech/tc2231/ .
Para mí esto resuelve el problema:
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(data)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileNameStar = "foo-ä-€.html"
};
Cuando miro el anuncio en repsonse violinista puedo ver el nombre del archivo automaticcaly se ha codificado con UTF-8:
ejemplo respuesta Fiddler con codificada Content-Disposition Nombre de archivo Con UTF-8
Si nos fijamos en el valor de la cabecera Content-Disposición podemos ver que será el mismo que @Johannes Geyer su respuesta. La única diferencia es que no tenemos que hacer nosotros solos los de codificación, la clase ContentDispositionHeaderValue se encarga de eso.
I utiliza los casos de prueba para la cabecera Content-Disposición en: http://greenbytes.de/tech/ tc2231 / como se ha mencionado por Julian Reschke. Información sobre la clase ContentDispositionHeaderValue se puede encontrar en MSDN.
Para Asp.Net Core (versión 2 de este post) UrlPathEncode está en desuso, aquí es cómo lograr el resultado deseado:
System.Net.Mime.ContentDisposition cd = new System.Net.Mime.ContentDisposition
{
FileName = Uri.EscapeUriString(fileName),
Inline = true // false = prompt the user for downloading; true = browser to try to show the file inline
};
Response.Headers.Add("Content-Disposition", cd.ToString());
I `m usando Uri.EscapeUriString
para convierte todos los caracteres a su representación hexadecimal, y string.Normalize
para la forma Unicode normalización C.
(Probado en ASP.NET MVC5 marco 4.5)
var contentDispositionHeader = new System.Net.Mime.ContentDisposition
{
Inline = false,
FileName = Uri.EscapeUriString(Path.GetFileName(pathFile)).Normalize()
};
Response.Headers.Add("Content-Disposition", contentDispositionHeader.ToString());
string mimeType = MimeMapping.GetMimeMapping(Server.MapPath(pathFile));
return File(file, mimeType);