Наверняка всем знаком заголовок "Content-Disposition" со значением "attachment; filename". Казалось бы, что может быть проще. Но оказывается и здесь есть свои нюансы. Для меня эти нюансы вылились в то, что при тестировании нормально filename определяла только Opera. Ослик сохранял файл с именем вида B_0JzQsNC70YzRh9C40LrQ. FireFox при сохранении файлов в именах которых содержатся пробелы, сохранял файл с частъю имени до первого пробела.
Впрочем проблемы возникали не только у меня:
1) http://softwaremaniacs.org/forum/django/14097/
2) http://sql.ru/forum/actualthread.aspx?tid=584761
3) http://www.gotdotnet.ru/forums/4/61117/294999/#post294999
но работающего решения так и не было найдено.
После более детального изучения проблемы и "доработки напильником" выяснилось, что IE понимает не ASCII имена файлов только в формате URL Encoding. А FireFox единственный который нуждается в обрамлении имени файла двойными ковычками. Таким образом получили работающий кроссбраузреный attachment; filename. Код выглядит следующим образом:
string fileName = fileInfo.Name;
if (IsIE(Request.Browser))
{
fileName = Server.UrlEncode(fileInfo.Name);
if (fileName != null) fileName = fileName.Replace(@"+", @"%20");
}
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\";");
Работает для IE8, FF3.5.5, Opera 10.10
пʼятниця, 4 грудня 2009 р.
Кроссбраузерный "Content-Disposition" "attachment; filename"
Мітки:
asp.net,
attachment; filename,
Content-Disposition,
FireFox,
IE,
Opera
Підписатися на:
Дописати коментарі (Atom)
как бы получить за одно код функции IsIE?
ВідповістиВидалитиprotected static bool IsIE(HttpBrowserCapabilities browser)
Видалити{
bool isIE = Utils.GetBrowserType(browser) == "IE";
return isIE;
}
public static string GetBrowserType(HttpBrowserCapabilities browser)
{
string result = "";
if (IsContaineType(browser, "mozil"))
result = "Mozilla";
if (IsContaineType(browser, "opera"))
result = "Opera";
if (IsContaineType(browser, "ie"))
result = "IE";
if (IsContaineType(browser, "netscape"))
result = "Mozilla";
if (IsContaineType(browser, "internet"))
result = "IE";
if (IsContaineType(browser, "safari"))
result = "Safari";
return result;
}
private static bool IsContaineType(HttpBrowserCapabilities browser, string type)
{
HttpBrowserCapabilities bc = browser;
bool result = false;
foreach (string bt in bc.Browsers)
{
result = bt.ToLower().StartsWith(type);
if (result) break;
}
return result;
}