Unicode en-tête Content-Disposition
-
23-09-2019 - |
Question
J'utilise enfant objet HttpContext mis en œuvre HttpHandler télécharger un fichier, quand j'ai des caractères non-ascii dans le nom du fichier, il fait un peu bizarre dans IE alors qu'il semble très bien dans Firefox.
Voici le code: -
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();
quand je l'offre « AY » « å¤ » « ¶ » « ü » « ó » « AY » « å¤ » « ¶ » « ü » « ó » dans le champ Nom de fichier, il est différent de ce que je ont le nom de fichier, il semble très bien dans firefox. ajoutant EncodingType et charset a été d'aucune utilité.
dire qu'il est 'Ãâ' 'ä' 'ö' 'ü' 'ó' 'Ãâ' 'ä' 'ö' 'ü' _ 'ó' et dans Firefox, il est AY ' 'å¤' '¶' 'ü' 'ó' 'AY' « å¤ ' '¶' 'ü' 'ó'.
Toute idée de comment cela peut être résolu?
La solution
J'ai eu le même problème. Vous devez utiliser HttpUtility.UrlEncode ou < a href = "http://msdn.microsoft.com/en-us/library/ms525738.aspx" rel = "noreferrer"> Server.UrlEncode pour coder le nom de fichier. Je me souviens aussi de Firefox n'a pas besoin. Moreoverit ruiné nom quand il est codé url. Mon code:
// 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);
Modifier
J'ai lu plus attentivement les spécifications. Tout d'abord RFC2183 indique que:
grammaire [RFC 2045] actuelle limite les valeurs des paramètres (et par conséquent les noms de fichiers Content-Disposition) à US-ASCII.
Mais je trouve que les références [RFC 2045] est et il faut perimés accepter la référence RFC 2231 , qui indique:
Asterisks ( "*") sont réutilisés pour fournir l'indicateur que la langue et caractère informations contenues est présent et le codage est utilisé. Un seul citation ( « ' ») est utilisé pour délimiter la jeu de caractères et d'information langue au début du paramètre valeur. signes de pourcentage ( « % de ») sont utilisés comme le drapeau de l'encodage, ce qui est d'accord avec RFC 2047.
Ce qui signifie que vous pouvez utiliser UrlEncode pour les symboles non-ascii, tant que vous incluez le codage comme indiqué dans la section
Autres conseils
HttpUtility.UrlPathEncode pourrait être une meilleure option. Comme URLEncode remplacera les espaces avec des signes '+'.
Pour moi, cette solution fonctionne sur tous les principaux navigateurs:
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);
Utilisation de ASP.NET MVC 3.
Le remplacer est nécessaire, parce que Chrome n'aime pas Virgule (,) des valeurs de paramètres: http://www.gangarasa.com/lets-Do-GoodCode/tag/err_response_headers_multiple_content_disposition/
Vous pouvez lire RFC 6266 et regarder les essais à http://greenbytes.de/tech/tc2231/ .
Pour moi, ce a résolu le problème:
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(data)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileNameStar = "foo-ä-€.html"
};
Quand je regarde annonce le repsonse dans Fiddler je peux voir le nom de fichier a été automaticcaly codé en utilisant UTF-8:
exemple de réponse avec le nom de fichier Fiddler Content-Disposition codé en utilisant UTF-8
Si l'on regarde la valeur de l'en-tête Content-Disposition nous pouvons le voir sera le même que celui @Johannes Geyer sa réponse. La seule différence est que nous ne devions pas faire les ourselfs d'encodage, la classe ContentDispositionHeaderValue prend soin de cela.
je les TestCases pour l'en-tête Content-Disposition sur: http://greenbytes.de/tech/ tc2231 / comme mentionné par Julian Reschke. Informations sur la classe ContentDispositionHeaderValue se trouve sur MSDN.
Pour Asp.Net de base (version 2 à partir de ce post) UrlPathEncode est dépréciée, voici comment obtenir le résultat souhaité:
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());
`m en utilisant Uri.EscapeUriString
pour tous les caractères convertis à leur représentation hexadécimale, et string.Normalize
pour un formulaire de normalisation Unicode C.
(Testé dans le framework ASP.NET MVC5 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);