Unicode in Content-Disposition-Header
-
23-09-2019 - |
Frage
Ich bin mit Httpcontext-Objekt implementiert in Httphandler Kind, eine Datei herunterzuladen, wenn ich nicht-ASCII-Zeichen in Dateinamen habe es in IE komisch aussieht, während es in Firefox aussieht.
unten ist der 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();
wenn ich liefern ‚ay‘ ‚夑 ‚ö‘ ‚ü‘ ‚ó‘ ‚ay‘ ‚夑 ‚ö‘ ‚ü‘ ‚ó‘ in Dateiname Feld, um es anders aussieht als das, was ich haben in Dateinamen in Firefox es aussieht. Hinzufügen EncodingType und charset zwecklos gewesen ist.
In dh es ist 'Ãâ' 'ä' 'ö' 'ü' 'ó' 'Ãâ' 'ä' 'ö' 'ü' _ 'ó' und in firefox es 'ay' 'å¤' 'ö' 'ü' 'ó' 'ay' ‚å¤ ' 'ö' 'ü' 'ó'.
Jede Idee, wie dieses Problem behoben werden kann?
Lösung
Ich hatte ähnliches Problem. Sie müssen verwenden HttpUtility.UrlEncode oder < a href = "http://msdn.microsoft.com/en-us/library/ms525738.aspx" rel = "noreferrer"> Server.UrlEncode zu kodieren Dateinamen. Ich auch nicht vergessen, Firefox hat es nicht brauchen. Moreoverit ruiniert Dateinamen, wenn es die URL-codiert. Mein 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);
Bearbeiten
Ich habe Spezifikation mehr sorgfältig zu lesen. Vor allem RFC2183 besagt, dass:
Current [RFC 2045] Grammatik einengt Parameterwerte (und damit Content-Disposition Dateinamen) auf US-ASCII.
Aber dann fand ich Hinweise, dass [RFC 2045] verworfene ist und man muss RFC 2231 , in dem es heißt:
Sternchen ( "*") werden wieder verwendet zu schaffen die Anzeige, dass die Sprache und Zeichensatzinformation vorhanden ist und die Codierung verwendet wird. Ein einzelner Zitat ( „'“) verwendet, die zur Abgrenzung Zeichensatz und Sprachinformationen zu Beginn des Parameters Wert. Prozentzeichen ( „%“) verwendet werden, wie Die Codierung Flagge, die mit stimmt RFC 2047.
Was bedeutet, dass Sie UrlEncode für Nicht-ASCII-Zeichen verwenden können, solange Sie die Codierung umfassen, wie in der
Andere Tipps
HttpUtility.UrlPathEncode könnte eine bessere Option sein. Wie URLEncode ersetzt Räume mit '+' Zeichen.
Für mich ist diese Lösung funktioniert auf allen gängigen Browsern:
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);
Mit ASP.NET MVC 3.
Ersetzen Das ist notwendig, da Chrome nicht wie Komma (,) in Parameterwerten: http://www.gangarasa.com/lets-Do-GoodCode/tag/err_response_headers_multiple_content_disposition/
Sie möchten RFC 6266 und Blick auf die Tests unter http://greenbytes.de/tech/tc2231/ .
Für mich hat das Problem gelöst:
var result = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new ByteArrayContent(data)
};
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileNameStar = "foo-ä-€.html"
};
Wenn ich Anzeige sehen die repsonse in Fiedler i den Dateinamen zu sehen ist automaticcaly codiert wurde unter Verwendung von UTF-8:
Fiddler Antwort Beispiel mit codierter Content-Disposition Dateinamen mit UTF-8
Wenn wir den Wert der Header Content-Disposition aussehen können wir sehen, es wird die gleiche wie @Johannes Geyer seine Antwort sein. Der einzige Unterschied besteht darin, dass wir nicht die Codierung ourselfs zu tun hatte, die ContentDispositionHeaderValue Klasse kümmert sich darum.
habe ich die Testfälle für die Content-Disposition-Header an: http://greenbytes.de/tech/ tc2231 / wie von Julian Reschke erwähnt. Informationen über die ContentDispositionHeaderValue Klasse kann auf MSDN.
Für Asp.Net Core (Version 2 als von diesem Post) UrlPathEncode ist veraltet, hier ist, wie das gewünschte Ergebnis zu erzielen:
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 mit Uri.EscapeUriString
für Konvertiten alle Zeichen in ihre hexadezimale Darstellung und string.Normalize
für Unicode-Normalisierungsform C
(Getestet in ASP.NET MVC5 Rahmen 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);