Какая разница между четырьмя результатами файлов в ASP.NET MVC
ASP.NET имеет четыре разных типа файлов:
- FileContentResult: отправляет содержимое двоичного файла в ответ.
- FilePathResult: отправляет содержимое файла в ответ
- FileResult: возвращает двоичный вывод для записи в ответ
- FileStreamResult: отправляет двоичный контент в ответ с помощью экземпляра Stream
Эти описания берутся из MSDN и, за исключением FileStreamResult, первые три звука идентичны. Так в чем же разница между ними?
Ответы
Ответ 1
FileResult
- это абстрактный базовый класс для всех остальных.
-
FileContentResult
- вы используете его, когда у вас есть байтовый массив, который вы хотите вернуть в виде файла -
FilePathResult
- когда у вас есть файл на диске и вы хотите вернуть его содержимое (вы FilePathResult
путь) -
FileStreamResult
- у вас есть открытый поток, вы хотите вернуть его содержимое в виде файла
Однако вам редко придется использовать эти классы - вы можете просто использовать одну из перегрузок Controller.File
и позволить ASP.NET MVC сделать магию за вас.
Ответ 2
Отличный вопрос... и заслуживает более подробной информации. Я оказался здесь в результате интересной ситуации. Мы поставляли некоторые вложения PDF через среду MVC3/С#. Наш код был выпущен, и мы начали получать ответы от наших клиентов о том, что загрузки ведут себя странно, когда они используют Chrome, и тип файла был преобразован в "pdf-, attachment.pdf-, attachment". Да... ты понял... все. Таким образом, можно было бы переписать его просто "pdf", и файл все равно сохранил бы неповрежденный, но какой беспорядок!
Итак, чтобы описать начальную ситуацию, мы устанавливали заголовок Content-Disposition, а затем возвращали FileContentResult...
var cd = new System.Net.Mime.ContentDisposition
{
FileName = result.Attachment.FileName,
Inline = false
};
Response.AppendHeader("Content-Disposition", cd.ToString());
return File(result.Attachment.Data, MimeExtensionHelper.GetMimeType(result.Attachment.FileName), result.Attachment.FileName);
Казалось, хорошо. Работал отлично в IE. Поэтому я провел некоторое исследование и попытался реализовать FileStreamResult вместо этого (поддерживая Set-Content Setter):
MemoryStream dataStream = new MemoryStream();
dataStream.Write(result.Attachment.Data, 0, result.Attachment.Data.Length);
dataStream.Position = 0;
return new FileStreamResult(dataStream, MimeExtensionHelper.GetMimeType(result.Attachment.FileName));
Он исправил проблему в Chrome! Hmmm... но почему в heck я должен взять свой превосходный массив байтов и передать его, а затем вернуть его через это, чтобы получить правильное имя файла?
Затем появился скрипач.
С FileContentResult я получил 2 Content-Dispositions в заголовке.
С FileStreamResult я получил 1.
FileContentResult добавляет заголовок Content-Disposition при предоставлении имени файла, а Chrome рассматривает кратность этого заголовка как ошибку.
Нечетная реакция... но определенно одна, что хорошо знать.