MVC - Браузеры не показывают расширение файлов .chm при загрузке

user7320

Возвращаю файл обычным методом (пробовал два варианта):
public FileResult DownloadContent(...)
{
 return File(fileContent, "application/x-chm", "fileName");
}

public FileResult DownloadContent(...)
{
 return File(fileContent, "application/x-chm", "fileName.chm");
}
Но в любом случае браузер пишет, что мол не знаю такого приложения и расширение не показывает. Пробовал в Опере и ИЕ. Лишь когда в Опере указал в настройках (Tools - Preferences - Downloads - Add - File Type), что такой тип файлов существует, так она стала добавлять и расширения, и программу сразу узнала, что такая существует (HTML Help называется).Как сделать так, чтобы браузеры сразу понимали, что я им такой файл посылаю? Я же им и MIME-тип, и даже расширение руками приписал к имени файла (во втором случае). Разве этого недостаточно, чтобы просто приписать расширение к имени файла и не заставлять пользователя гадать, что это я ему за фигню подсовываю, о которой даже браузер не знает. Ведь не заставишь же каждого пользователя в своём браузере добавить настройки для закачек этого типа файлов, а по умолчанию этих настроек в браузерах почему-то нет.
14 ответов

user7320

Response.AppendHeader("content-disposition", "attachment; filename=" + Server.HtmlEncode(myFilename));


user7320

SanSYS, это мвц :)


user7320

SanSYS, это мвц :)
Да, МВЦ. А что, там по-другому? Вроде, знакомые штучки - респонс там, ХТМЛэнкоде всякие - завтра попробую.А как в МВЦ тогда правильно это сделать?


user7320

SanSYS, это мвц :)
Эх, точно!


user7320

Да, МВЦ. А что, там по-другому? Вроде, знакомые штучки - респонс там, ХТМЛэнкоде всякие - завтра попробую.А как в МВЦ тогда правильно это сделать?
Хм.. попробуй тип указать application/octet-stream ну или MediaTypeNames.Application.Octet


user7320

Да, МВЦ. А что, там по-другому? Вроде, знакомые штучки - респонс там, ХТМЛэнкоде всякие - завтра попробую.А как в МВЦ тогда правильно это сделать?
ControllerContext.HttpContext
public class ... : ActionResult 
{ 
 public override void ExecuteResult(ControllerContext context) 
 {
 ...
 }
}


user7320

Я не очень понял код, который вы мне предлагаете, но я так понял, что надо поработать с заголовками ХТТП.Вобщем, проблема частично решилась - это я по невнимательности не туда посмотрел и не тот код запустил. Короче говоря, если указать расширение файла в его имени, как во втором варианте у меня в первом посте, то все нормальные браузеры всё понимают и правильно определяют тип файлов... Но есть такая вещь, как ИЕ 8 - ему не только не хватает расширения в имени, но даже если указать перед отправкой файла заголовок с инфой о типе отправляемых данных в ответе, он всё равно ничего не понимает:
[HttpGet]
public FileResult DownloadContent(..., Guid? entityId, ...)
{ 
	...// fileToDownload initialization
	
	HttpContext.Response.AddHeader("Content-Type", application/x-chm);

	return File(fileToDownload.Content, fileToDownload.MIME, fileToDownload.NameWithExtension);
}
ИЕ 8 пишет при попытке загрузки, что "Тип: неизвестный тип файла", а имя почему-то совпадает с параметром entityId действия DownloadContent. Я не могу понять логику ИЕ - а почему id, почему не какой-нибудь другой параметр (там их три, причём два оставшихся - стринговые)? Далее, при попытке сохранить на диске, когда выбирается, в какой каталог сохранить, он в имени файла пишет этот айдишник без расширения (нормальные браузеры пишут имя файла с расширением - fileToDownload.NameWithExtension), а в типе файла - "Все типы файлов", как будто я ему MIME не посылаю.Что ещё нужно указать ИЕ, чтобы он понял, что это chm?


user7320

-- HttpContext.Response.AddHeader("Content-Type", application/x-chm);На самом деле
HttpContext.Response.AddHeader("Content-Type", "application/x-chm");


user7320

Да, кстати, я в дебаге глянул - если не указать явно заголовок с типом контента, то параметр Response.ContentType будет "text/html", что, однако, не мешает нормальным браузерам распознать файл при загрузке. А вот почему FileResult в MVC при возврате не устанавливает заголовки? Или это что-то типа устаревших формальностей и для нормальных браузеров не нужно?


user7320

Я не очень понял код, который вы мне предлагаете, но я так понял, что надо поработать с заголовками ХТТП...
МСУ, должно быть, имел ввиду то, что необходимо использовать контекст предоставленный контроллером, подозреваю что это просто this.Context


user7320

Да, имелось ввиду юзать из контекста. Или свой ActionResult / FileResult сделать под конкретный экшен.


user7320

МСУ, должно быть, имел ввиду то, что необходимо использовать контекст предоставленный контроллером, подозреваю что это просто this.Context
Да, имелось ввиду юзать из контекста. Или свой ActionResult / FileResult сделать под конкретный экшен.
Ну я его и использую. А дальше-то как? Там выше человек написал что-то, связанное с заголовками, как я понял. В свойствах контекста есть функция добавления заголовков (я написал), но как и что написать, чтобы ИЕ понял, что это у меня за файл, я не знаю. Я самый очевидный заголовок добавил - ИЕ не понял. Опера и Фаер Фокс понимают всё и без заголовков, а Фаер Форкс - даже без регистрации в нём такого типа файлов расширения и MIME'а.Я хочу, чтобы ИЕ понимал этот файл без дополнительной работы по его настройке - юзер же не будет настраивать свой браузер, чтобы понять, что за фигню он у меня пытается загрузить.


user7320

А, понял:
[HttpGet]
public FileResult DownloadContent(...)
{
	FileToDownloadModel fileToDownload = ...;

	HttpContext.Response.AppendHeader(
		"content-disposition",
		"attachment; filename=" + HttpUtility.UrlPathEncode(fileToDownload.Name));

	return File(fileToDownload.Content, fileToDownload.MIME, fileToDownload.Name);
}


user7320

user7320, RTFM. Уже всё сказано.