2010-03-30 8 views
7

Używam obiektu HttpContext zaimplementowanego w pliku potomnym HttpHandler do pobrania pliku, gdy mam w nazwie pliku znaki inne niż ascii, wygląda dziwnie w IE, podczas gdy w przeglądarce Firefox wygląda dobrze.Unicode w nagłówku Content-Disposition

poniżej kod: -

 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(); 

kiedy dostarczamy 'ay' 'å¤' 'ö ¼' '' '' 'ó ay' 'å¤' '' „¼ ö "Ó" w polu nazwy pliku wygląda inaczej niż nazwa pliku w firefoxie. dodanie kodu EncodingType i zestawu znaków jest bezużyteczne.

w IE jest to 'ÃÂ' 'ä' 'ö' 'ü' 'ó' 'ÃÂ' 'ä' 'ö' „ü'_ "ó³" i w firefoxie to "ß" "ä" "à ¼" "Ó" "ß" "ä" "à '" "¼¼" "Ó".

Każdy pomysł, jak to naprawić?

+0

Czy to jest zawartość pliku, czy sama nazwa pliku? – leppie

+0

@leppie, to sama nazwa pliku – Ranjeet

Odpowiedz

12

Miałem podobny problem. Do kodowania nazwy pliku należy użyć HttpUtility.UrlEncode lub Server.UrlEncode. Pamiętam też, że firefox go nie potrzebował. Co więcej, zrujnowana nazwa pliku, gdy jest kodowana przez URL. Mój kod:

// 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); 

Edit

mam bardziej uważnie przeczytać specyfikację. Przede wszystkim RFC2183 stwierdza:

prądu [RFC 2045] gramatyka ogranicza wartości parametrów (a więc Content-Disposition nazwy plików) US-ASCII.

Ale potem znalazłem odniesienia, które [RFC 2045] jest absolete i trzeba odwoływać RFC 2231, który stanowi:

gwiazdką ("*") są ponownie wykorzystywane w celu zapewnienia wskaźnik ten język i informacje o zestawie znaków są obecne i używane jest kodowanie. Pojedyncza wycena ("") służy do ograniczenia zestawu znaków i informacji językowych na temat wartości parametru . Znaki procent („%”) są wykorzystywane jako flagę kodowania, który zgadza się z RFC 2047.

co oznacza, że ​​można użyć urlencode symbole non-ASCII, jak powiedziałem wcześniej, ale można też dodać opis kodowania. Oto przykład:

string.Format("attachment; filename*=UTF-8''{0}", Server.UrlEncode(fileName)); 

nie spróbować chociaż ..

+0

@Sergej, próbowałem tego co powiedziałeś i działa dobrze, czy możesz wyjaśnić, dlaczego zepsuło to nazwę pliku, tak, że mam to jasno w głowie zanim faktycznie to zaimplementuję. – Ranjeet

+0

Zgodnie z odpowiedzią Asha użyłem tego, ale z 'UrlPathEncode', który działał jak czar (nie dodaje znaków" + "). – Andrew

5

HttpUtility.UrlPathEncode może być lepszą opcją. Ponieważ URLEncode zastąpi spacje znakami "+".

3

Dla mnie to rozwiązanie działa na wszystkich głównych przeglądarek:

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); 

Korzystanie ASP.NET MVC 3.

Zastąp jest konieczne, ponieważ Chrome nie jak przecinek (,) w parametrze wartości: http://www.gangarasa.com/lets-Do-GoodCode/tag/err_response_headers_multiple_content_disposition/

1

Dla mnie to rozwiązało problem:

var result = new HttpResponseMessage(HttpStatusCode.OK) 
{ 
    Content = new ByteArrayContent(data) 
}; 

result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") 
{ 
    FileNameStar = "foo-ä-€.html" 
}; 

Kiedy patrzę AD repsonse w Skrzypek widzę nazwę pliku został automaticcaly zostały zakodowane przy użyciu UTF-8:

Fiddler response example with encoded Content-Disposition filename using UTF-8

Jeśli spojrzymy na wartość nagłówka Content-Dyspozycja widzimy to będzie taki sam jak @Johannes Geyer jego odpowiedź. Jedyna różnica polega na tym, że nie musieliśmy samodzielnie kodować, klasa ContentDispositionHeaderValue zajmuje się tym.

Użyłem testcases dla nagłówka Content-Disposition na: http://greenbytes.de/tech/tc2231/ jak wspomniał Julian Reschke. Informacje na temat klasy ContentDispositionHeaderValue można znaleźć w witrynie MSDN.